+2009-04-23 Marcelo Vanzin <mvanzin@vmware.com>
+ * Resync with internal trunk (2009.04.17)
+
+ * configure.ac, Makefile.am, docs/*: build API docs for vmtools; the
+ documentation files are provided under a BSD-style license.
+
+ * configure.ac, Makefile.am, guestd/*, lib/Makefile.am, lib/guestInfo/*,
+ lib/include/vmbackup_def.h, lib/include/vmBackup.h, lib/vmBackupLib/*,
+ libvmtools/Makefile.am, services/plugins/vmbackup/vmbackup_def.h: remove
+ guestd from open-vm-tools, and clean up code in other places that was only
+ there because of guestd.
+
+ * configure.ac, modules/solaris/vmblock/*, modules/solaris/vmmemctl/*: add
+ Solaris vmblock and vmmemctl driver sources. The vmmemctl module also
+ includes a user-level daemon (vmmemctld.c).
+
+ * lib/conf/conf.c, lib/include/conf.h, libvmtools/vmtoolsConfig.c: remove
+ unused config options.
+
+ * lib/deployPkg/toolsDeployPkg.h: code refactoring.
+
+ * lib/dnd/dndClipboard.c: if size of clipboard exceeds the maximum backdoor
+ packet size, only keep text data (dropping the RTF data).
+
+ * lib/dnd/dndLinux.c, lib/include/dnd.h, lib/include/vmblock.h,
+ vmware-user/copyPaste.c, vmware-user/dnd.c, vmware-user/vmware-user.cpp,
+ vmware-user/vmwareuserint.h, vmware-user-suid-wrapper/main.c: detect
+ whether plain vmblock or vmblock-fuse is being used, allowing the same
+ executable to be used with either.
+
+ * lib/dndGuest/*, vmware-user/copyPaseDnDWrapper.{cpp,h},
+ vmware-user/dndUI.{cpp,h}, vmware-user/dragDetWnd.{cpp,h}:
+ vmware-user/vmware-user.cpp: more DnD V3 protocol work.
+
+ * lib/ghIntegration/*, lib/include/guestCaps.h, lib/include/unityCommon.h:
+ work related to mapping Outlook folders over HGFS and exposing the Windows
+ Recycle Bin to the host (doesn't really affect open-vm-tools).
+
+ * lib/ghIntegration/ghIntegrationX11.c: restore the native environment when
+ launching external applications. This doesn't really affect open-vm-tools.
+
+ * lib/guestRpc/*, vmware-user/copyPasteUI.{cpp,h}: implement RTF and file
+ contents copy & paste.
+
+ * lib/include/circList.h, lib/include/vm_basic_math.h,
+ lib/include/vm_device_version.h, modules/linux/*, modules/Makefile.am:
+ changes to share files between the user space code and the kernel code,
+ instead of duplicating the same source files in different places.
+
+ * lib/include/rpcChannel.h, lib/rpcChannel/*, tests/testDebug/testDebug.c,
+ test/vmrpcdbg/debugChannel.c: some code cleanup, and fix crash when dealing
+ with multiple reset messages.
+
+ * lib/include/system.h, lib/system/systemLinux.c,
+ services/vmtoolsd/mainPosix.c: remove System_Daemon() (replaced with
+ Hostinfo_Daemonize()).
+
+ * lib/include/unityCommon.h, lib/unity/*: ressurrect UNITY_RPC_WINDOW_SHOW
+ and UNITY_RPC_WINDOW_HIDE RPCs.
+
+ * lib/procMgr/procMgrPosix.c: fix ProcMgr_IsProcessRunning().
+
+ * lib/system/systemLinux.c: fix shutdown / reboot commands on Solaris; fix
+ rebuilding of native environment from variables set by VMware scripts (this
+ last one doesn't really affect open-vm-tools).
+
+ * lib/unicode/unicodeSimpleTypes.c: speed up UnicodeIANALookup, and fix case
+ where C++ constructors could call UnicodeIANALookup before Unicode_Init()
+ was called by lazily creating the internal cache.
+
+ * libguestlib/*: link libguestlib against libvmtools. This avoids having
+ two definitions of certain symbols (like Debug()) when an application
+ links to both libraries.
+
+ * modules/linux/vmblock/linux/control.c: only set directory entry owner when
+ needed.
+
+ * modules/linux/vmhgfs/bdhandler.{c,h}, modules/linux/vmhgfs/dir.c,
+ modules/linux/vmhgfs/file.c, modules/linux/vmhgfs/filesystem.c,
+ modules/linux/vmhgfs/fsutil.c, modules/linux/vmhgfs/inode.c,
+ modules/linux/vmhgfs/module.{c,h}, modules/linux/vmhgfs/page.c,
+ modules/linux/vmhgfs/request.{c,h}, modules/linux/vmhgfs/super.c,
+ modules/linux/vmhgfs/tcp.{c,h}, modules/linux/vmhgfs/transport.{c,h}:
+ cleanup use of atomic variables in HGFS; add a transport abstraction layer,
+ and add an initial version of a socket-based transport (not yet stable and
+ not yet supported by any released VMware product).
+
+ * modules/linux/vmxnet3/vmxnet3.c: fix build on kernel 2.6.29.
+
+ * modules/linux/vsock/af_vsock.c: export more functions to other kernel
+ modules; some changes to statistics gathering code.
+
+ * modules/solaris/vmhgfs/filesystem.c: make module loadable on Solaris 9.
+
+ * modules/solaris/vmhgfs/vnode.c: unify mapping of HGFS to Solaris error
+ codes.
+
+ * scripts/*: restart network before running user scripts in resume scripts.
+
+ * services/plugin/powerOps/powerOps.c: fix running default power scripts.
+
+ * services/vmtoolsd/pluginMgr.c: better error logging.
+
+ * toolbox/toolbox-cmd.c: fix help string.
+
+ * vmblock-fuse/block.c: fix vmblock-fuse compilation on FreeBSD.
+
2009-03-18 Marcelo Vanzin <mvanzin@vmware.com>
* Resync with internal trunk (2009.03.13)
SUBDIRS =
SUBDIRS += lib
SUBDIRS += libvmtools
-SUBDIRS += guestd
if HAVE_X11
SUBDIRS += $(X11_SUBDIRS)
endif
if WITH_KERNEL_MODULES
SUBDIRS += modules
endif
+SUBDIRS += docs
+
+open-vm-tools 2009.04.23 changes:
+ * Implemented copy & paste support for RTF data and file contents.
+
+ * guestd has been removed from open-vm-tools; vmtoolsd is now the only
+ option for the main tools service.
+
+ * Added vmblock and vmmemctl modules for Solaris (under the CDDL).
+
+ * vmware-user can now work with both vmblock-fuse and vmblock.
+
+ * Linux HGFS now has a stream-based (TCP, vsock) transport, still under
+ development.
+
+ * First batch of changes to cleanup duplicated files in the source tree.
+ Most duplicated files in the Linux kernel modules have been cleaned up.
+
open-vm-tools 2009.03.18 changes:
* Mostly a bug fix release.
### Initialization
###
+TOOLS_VERSION="2009.04.23"
AC_INIT(
[open-vm-tools],
- [2009.03.18],
+ [2009.04.23],
[open-vm-tools-devel@lists.sourceforge.net])
# In order to make this configure script auto-detect situations where
[with_gtkmm="$withval"],
[with_gtkmm="yes"])
+AC_ARG_ENABLE(
+ docs,
+ AS_HELP_STRING(
+ [--disable-docs],
+ [disables generation of API documentation; by default, docs are built if doxygen is available.]),
+ [enable_docs="$enableval"],
+ [enable_docs="yes"])
+
# If we're not going to use Gtk 2.0, disable Unity.
if test "$with_gtk2" != "yes"; then
enable_unity="no"
[AC_CHECK_LIB(
dl,
dlopen,
- GUESTD_LDADD="$GUESTD_LDADD -ldl",
+ LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -ldl",
[AC_MSG_ERROR(
[dlopen was not found, but is required for open-vm-tools to function properly. Please contact your OS vendor.])])])
[],
[],
[getstat],
- [GUESTD_LDADD="$GUESTD_LDADD $PROCPS_LIBS";
- VMWARE_USER_LDADD="$VMWARE_USER_LDADD $PROCPS_LIBS"],
+ [VMWARE_USER_LDADD="$VMWARE_USER_LDADD $PROCPS_LIBS"],
[AC_MSG_ERROR([libproc not found. Please configure without procps (using --without-procps) or install procps - http://procps.sourceforge.net])])
fi
fi
if test $have_dnet -eq 1; then
- GUESTD_LDADD="$GUESTD_LDADD $DNET_LIBS"
+ LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD $DNET_LIBS"
VMWARE_USER_LDADD="$VMWARE_USER_LDADD $DNET_LIBS"
else
AC_MSG_ERROR(
BLD_INCLUDE_DIR="$BUILDDIR/lib/include"
CPPFLAGS="-I$INCLUDE_DIR -I$BLD_INCLUDE_DIR $CPPFLAGS"
+###
+### Documentation.
+###
+
+if test "$enable_docs" = "yes"; then
+ AC_CHECK_PROG([have_doxygen],
+ [doxygen],
+ [yes],
+ [no])
+ if test "$have_doxygen" = "no"; then
+ AC_MSG_WARN([doxygen not found; API documentation will not be generated.])
+ else
+ AC_CHECK_PROG([HAVE_DOT],
+ [dot],
+ [yes],
+ [no])
+ if test "$HAVE_DOT" = "yes"; then
+ DOT=dot
+ else
+ DOT=
+ fi
+ AC_SUBST([DOT])
+
+ AC_PATH_PROG([MSCGEN],
+ [mscgen],
+ [no])
+ if test "$MSCGEN" != "no"; then
+ MSCGEN_DIR="`dirname $MSCGEN`"
+ else
+ MSCGEN_DIR=
+ fi
+ AC_SUBST([MSCGEN_DIR])
+ fi
+fi
+
+###
### OS/arch-specific flags / actions
+###
MODULES=""
MODULES_OS="$os"
LIB_IMPERSONATE_CPPFLAGS="$LIB_IMPERSONATE_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
LIB_USER_CPPFLAGS="$LIB_USER_CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
- GUESTD_LDADD="$GUESTD_LDADD -lsocket"
- GUESTD_LDADD="$GUESTD_LDADD -lnsl"
- GUESTD_LDADD="$GUESTD_LDADD -lrpcsvc"
+ LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lsocket"
+ LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lnsl"
+ LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lrpcsvc"
VMWARE_USER_CPPFLAGS="$VMWARE_USER_CPPFLAGS -I/usr/X11/include/"
VMWARE_USER_LDADD="$VMWARE_USER_LDADD -lXext"
fi
# Choose which modules to compile
- if test "$osVersion" -eq 510000; then
- MODULES="$MODULES vmblock"
- fi
if test "$osVersion" -ge 510000; then
- MODULES="$MODULES vmhgfs"
+ MODULES="$MODULES vmhgfs vmblock"
fi
- # We build vmxnet on Solaris 9 and 10
+ # We build vmxnet and vmballoon on Solaris 9 and 10
if test "$osVersion" -lt 511000 -a "$osVersion" -ge 509000; then
- MODULES="$MODULES vmxnet"
+ MODULES="$MODULES vmxnet vmmemctl"
fi
# Vmxnet3 is built on Solaris 10 only and only if GLDv3 is installed
AM_CONDITIONAL(PAMD, test -d /etc/pam.d)
AM_CONDITIONAL(ENABLE_UNITY, test "$enable_unity" = "yes")
AM_CONDITIONAL(WITH_ROOT_PRIVILEGES, test "$with_root_privileges" = "yes")
+AM_CONDITIONAL(HAVE_DOXYGEN, test "$have_doxygen" = "yes")
AM_CONDITIONAL(HAVE_FUSE, test "$have_fuse" = "yes")
AM_CONDITIONAL(HAVE_GNU_LD, test "$with_gnu_ld" = "yes")
AM_CONDITIONAL(HAVE_GTKMM, test "$have_x" = "yes" -a "$with_gtkmm" = "yes")
if test "$HAVE_CRYPT" = "yes"; then
LIB_AUTH_CPPFLAGS="$LIB_AUTH_CPPFLAGS -DGLIBC_VERSION_22"
- GUESTD_LDADD="$GUESTD_LDADD -lcrypt"
+ LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lcrypt"
VIX_LIBADD="$VIX_LIBADD -lcrypt"
fi
fi
if test "$HAVE_PTHREAD" = "yes"; then
- GUESTD_LDADD="$GUESTD_LDADD -lpthread"
+ LIBVMTOOLS_LIBADD="$LIBVMTOOLS_LIBADD -lpthread"
VIX_LIBADD="$VIX_LIBADD -lpthread"
VMWARE_USER_LDADD="$VMWARE_USER_LDADD -lpthread"
fi
### General substs
+AC_SUBST([TOOLS_VERSION])
AC_SUBST([TARGET_OS])
AC_SUBST([KERNEL_RELEASE])
AC_SUBST([MODULES_OS])
AC_SUBST([LIB_PROC_MGR_CPPFLAGS])
AC_SUBST([LIB_STRING_CPPFLAGS])
AC_SUBST([LIB_USER_CPPFLAGS])
-
-LIBVMTOOLS_LIBADD="$GUESTD_LDADD"
AC_SUBST([LIBVMTOOLS_LIBADD])
### Program substs
-AC_SUBST([GUESTD_LDADD])
AC_SUBST([VIX_LIBADD])
AC_SUBST([VMWARE_USER_CPPFLAGS])
AC_SUBST([VMWARE_USER_LDADD])
lib/unityWindowTracker/Makefile \
lib/user/Makefile \
lib/vixTools/Makefile \
- lib/vmBackupLib/Makefile \
lib/vmCheck/Makefile \
lib/vmSignal/Makefile \
lib/wiper/Makefile \
- guestd/Makefile \
services/Makefile \
services/vmtoolsd/Makefile \
services/plugins/Makefile \
tests/vmrpcdbg/Makefile \
tests/testDebug/Makefile \
tests/testPlugin/Makefile \
+ docs/Makefile \
+ docs/api/Makefile \
scripts/Makefile \
])
################################################################################
-### Copyright 2007 VMware, Inc. All rights reserved.
+### Copyright 2009 VMware, Inc. All rights reserved.
###
### This program is free software; you can redistribute it and/or modify
### it under the terms of version 2 of the GNU General Public License as
### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
################################################################################
-noinst_LTLIBRARIES = libVmBackupLib.la
+SUBDIRS =
-libVmBackupLib_la_SOURCES =
-libVmBackupLib_la_SOURCES += scriptOps.c
-libVmBackupLib_la_SOURCES += stateMachine.c
-libVmBackupLib_la_SOURCES += syncDriverOps.c
+if HAVE_DOXYGEN
+SUBDIRS += api
+endif
--- /dev/null
+################################################################################
+### Copyright 2009 VMware, Inc. All rights reserved.
+###
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of version 2 of the GNU General Public License as
+### published by the Free Software Foundation.
+###
+### This program is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with this program; if not, write to the Free Software
+### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+################################################################################
+
+DOXYGEN_INPUT =
+DOXYGEN_INPUT += $(top_srcdir)/docs/api
+DOXYGEN_INPUT += $(top_srcdir)/docs/api/services
+DOXYGEN_INPUT += $(top_srcdir)/lib/include/rpcChannel.h
+DOXYGEN_INPUT += $(top_srcdir)/lib/include/vmtoolsApp.h
+DOXYGEN_INPUT += $(top_srcdir)/lib/include/vmtools.h
+DOXYGEN_INPUT += $(top_srcdir)/lib/include/vmrpcdbg.h
+DOXYGEN_INPUT += $(top_srcdir)/libvmtools
+DOXYGEN_INPUT += $(top_srcdir)/tests/vmrpcdbg
+
+DOXYGEN_CPP_PREDEFINED =
+DOXYGEN_CPP_PREDEFINED += G_LOCK_DEFINE_STATIC(x)
+DOXYGEN_CPP_PREDEFINED += G_LOG_DOMAIN=
+
+DOXYGEN_CPP_EXPAND =
+
+# This rule has no dependencies, so it's executed every time. Not optimal,
+# but generation of the docs is pretty quick, and having the right dependencies
+# here is very non-trivial.
+build/index.html:
+ mkdir -p build
+ sed \
+ -e 's,##{BUILD_DIR}##,$(top_builddir),' \
+ -e 's,##{CPP_EXPAND}##,$(DOXYGEN_CPP_EXPAND),' \
+ -e 's,##{CPP_PREDEFINED}##,$(DOXYGEN_CPP_PREDEFINED),' \
+ -e 's,##{DOT}##,@DOT@,' \
+ -e 's,##{HAVE_DOT}##,@HAVE_DOT@,' \
+ -e 's,##{INPUT}##,$(DOXYGEN_INPUT),' \
+ -e 's,##{MSCGEN_DIR}##,@MSCGEN_DIR@,' \
+ -e 's,##{PROJECT_VERSION}##,@TOOLS_VERSION@,' \
+ -e 's,##{SOURCE_DIR}##,$(top_srcdir),' \
+ $(top_srcdir)/docs/api/doxygen.conf > doxygen.parsed.conf
+ doxygen doxygen.parsed.conf > /dev/null
+
+all-local: build/index.html
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(docdir)/api
+ cp -r build/* $(DESTDIR)$(docdir)/api
--- /dev/null
+###
+### profile-api.conf - "Public API" Doxygen profile. Includes only non-static
+### functions and non-internal documentation.
+###
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+PROJECT_NAME = "##{PROJECT_NAME}##"
+PROJECT_NUMBER = "##{PROJECT_VERSION}##"
+OUTPUT_DIRECTORY = ##{BUILD_OUTPUT}##
+TAB_SIZE = 3
+OPTIMIZE_OUTPUT_FOR_C = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = ##{CLIENT_ROOT}##
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+EXTRACT_LOCAL_CLASSES = NO
+
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = YES
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE = ##{WARNING_LOG}##
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+INPUT = ##{INPUT_PATHS}##
+FILE_PATTERNS = ##{FILE_PATTERNS}##
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+GENERATE_LATEX = NO
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+GENERATE_RTF = NO
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+GENERATE_MAN = NO
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+GENERATE_XML = NO
+
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+INCLUDE_PATH = ##{INCLUDE_PATHS}##
+
+PREDEFINED = ##{CPP_PREDEFINED}##
+EXPAND_AS_DEFINED = ##{CPP_EXPAND}##
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = ##{PERL}##
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH = ##{MSCGEN_DIR}##
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = ##{HAVE_DOT}##
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH = ##{DOT}##
+DOTFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = NO
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2008 VMware, 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.
+ * 3. Neither the name of VMware Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission of VMware Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *********************************************************/
+
+/**
+
+@defgroup vmtools_debug Debugging Tools Plugins
+
+@brief Defines functions and interfaces for debugging Tools plugins.
+
+This module provides functions for writing "debug plugins" - plugins which
+provide functionality for driving the Tools Services when they're running in
+"debug mode". Debug plugins are dynamically loaded by providing specific
+command-line options to the Tools service process.
+
+@section vmtools_debug_how How debug plugins work
+
+Currently, there's only support for GuestRPC-based debug plugins.
+
+The debug library implements an RPC channel that can be driven by a debug
+plugin, according to information provided by the plugin at load time.
+
+The debug plugin can provide two types of information:
+
+ - RPCs to be sent to the application: these are input to the application,
+ and can be tied to a validation function to make sure the response from
+ the application is correct.
+
+ - Validation functions for "outgoing" RPCs: these are functions called in
+ response to RPCs initiated by the applications; they can be mapped to
+ specific RPC command strings, to make writing the plugin easier.
+
+For more details, check the RpcDebugPlugin data structure.
+
+Plugins that depend on events that are not only responses to RPC messages (such
+as timer-based outgoing RPCs) should make sure they tell the library that it
+should not stop running by incrementing its ref count (see RpcDebug_IncRef()).
+When the test is complete, the code can then call RpcDebug_DecRef() and, when
+the ref count reaches zero, the main application loop will be stopped.
+
+*/
+
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2008 VMware, 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.
+ * 3. Neither the name of VMware Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission of VMware Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *********************************************************/
+
+/**
+
+@defgroup vmtools_guestrpc GuestRPC functions
+
+@brief Functions related to reading and writing data on a GuestRPC channel.
+
+*/
+
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2008 VMware, 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.
+ * 3. Neither the name of VMware Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission of VMware Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *********************************************************/
+
+/**
+
+@defgroup vmtools_plugins VMware Tools Plugins
+
+@brief Defines the API used by the Tools Services for dynamically loading plugins.
+
+Plugins are dynamically loaded into the Tools service process, and may
+provide applications that hook into the functionality provided by the
+service, such as the glib main loop and the GuestRPC channel.
+
+Plugins that want to remain loaded by the service should always return
+registration data when their registration function (ToolsPluginOnLoad())
+is called. The registration data, defined by the ToolsPluginData data structure,
+provides information about what events the plugin is interested in (for example,
+incoming RPCs).
+
+*/
+
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2008 VMware, 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.
+ * 3. Neither the name of VMware Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission of VMware Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *********************************************************/
+
+/**
+
+@defgroup vmtools_utils Utility Functions
+
+@brief A collection of useful functions for when writing applications.
+
+This module contains functions for loading configuration data, logging, and
+extensions to the glib API that are useful when writing applications.
+
+@section vmtools_utils_log Configuring Logging
+
+Logging is configurable on a per-domain basis. The configuration options
+for each domain are:
+
+ - level: minimum log level to log. Also used to declare specific log
+ domain configurations.
+ - Valid values: error, critical, warning, message, info, debug, none
+ - This value is required when configuring a domain.
+ - handler: the handler to use when logging.
+ - Valid values: std, outputdebugstring (Win32-only), file
+ - Default: "std" on Unix, "outputdebugstring" on Windows.
+ - data: optional configuration data for the handler.
+ - Required for the "file" handler (path to log file).
+
+Logging configuration should be under the "[logging]" group in the
+application's configuration file.
+
+Each application can specify a default log domain (which defaults to
+"vmtools"). If no handler is specified for a particular domain when
+logging, the default handler will be used. The default logging level
+for the default domain is "warning" in non-debug builds, and "message"
+in debug builds.
+
+Example of logging configuration in the config file:
+
+@verbatim
+[logging]
+# Turns on logging globally. It can still be disabled for each domain.
+log = true
+
+# Disables core dumps on fatal errors; they're enabled by default.
+enableCoreDump = false
+
+# Defines the "vmsvc" domain, logging to stdout/stderr.
+vmsvc.level = info
+vmsvc.handler = std
+
+# Defines the "unity" domain, logging to a file.
+unity.level = warning
+unity.handler = file
+unity.data = /tmp/unity.log
+
+# Defines the "vmtoolsd" domain, and disable logging for it.
+vmtoolsd.level = none
+@endverbatim
+
+Log file names can contain variable references. Currently, only two variables
+are expanded: @a ${USER} expands to the current user's login name, and @a ${PID}
+expands to the current process's ID. So, for example, @a log.${USER}.${PID}.txt
+would expand to "log.jdoe.1234.txt" for user "jdoe" if the process ID were 1234.
+
+*/
+
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
+++ /dev/null
-################################################################################
-### Copyright 2007 VMware, Inc. All rights reserved.
-###
-### This program is free software; you can redistribute it and/or modify
-### it under the terms of version 2 of the GNU General Public License as
-### published by the Free Software Foundation.
-###
-### This program is distributed in the hope that it will be useful,
-### but WITHOUT ANY WARRANTY; without even the implied warranty of
-### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-### GNU General Public License for more details.
-###
-### You should have received a copy of the GNU General Public License
-### along with this program; if not, write to the Free Software
-### Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-################################################################################
-
-sbin_PROGRAMS = vmware-guestd
-
-AM_CFLAGS = -I$(top_builddir)/include
-AM_CFLAGS += -I$(top_srcdir)/services/plugins/vix
-
-vmware_guestd_LDADD =
-vmware_guestd_LDADD += ../lib/backdoor/libBackdoor.la
-vmware_guestd_LDADD += ../lib/conf/libConf.la
-vmware_guestd_LDADD += ../lib/dnd/libDnd.la
-vmware_guestd_LDADD += ../lib/err/libErr.la
-vmware_guestd_LDADD += ../lib/eventManager/libEventManager.la
-vmware_guestd_LDADD += ../lib/file/libFile.la
-vmware_guestd_LDADD += ../lib/guestApp/libGuestApp.la
-vmware_guestd_LDADD += ../lib/guestInfo/libGuestInfo.la
-vmware_guestd_LDADD += ../lib/guestRpc/libGuestRpc.la
-vmware_guestd_LDADD += ../lib/hgfsServer/libHgfsServer.la
-vmware_guestd_LDADD += ../lib/hgfsServerManagerGuest/libHgfsServerManagerGuest.la
-vmware_guestd_LDADD += ../lib/hgfsServerPolicyGuest/libHgfsServerPolicyGuest.la
-vmware_guestd_LDADD += ../lib/deployPkg/libDeployPkg.la
-vmware_guestd_LDADD += ../lib/impersonate/libImpersonate.la
-vmware_guestd_LDADD += ../lib/netUtil/libNetUtil.la
-vmware_guestd_LDADD += ../lib/printer/libPrinter.la
-vmware_guestd_LDADD += ../lib/procMgr/libProcMgr.la
-vmware_guestd_LDADD += ../lib/rpcIn/libRpcIn.la
-vmware_guestd_LDADD += ../lib/rpcOut/libRpcOut.la
-vmware_guestd_LDADD += ../lib/rpcVmx/libRpcVmx.la
-vmware_guestd_LDADD += ../lib/SLPv2Parser/libSLPv2Parser.la
-vmware_guestd_LDADD += ../lib/socketMgr/libSocketMgr.la
-vmware_guestd_LDADD += ../lib/string/libString.la
-vmware_guestd_LDADD += ../lib/sync/libSync.la
-vmware_guestd_LDADD += ../lib/syncDriver/libSyncDriver.la
-vmware_guestd_LDADD += ../lib/system/libSystem.la
-vmware_guestd_LDADD += ../lib/user/libUser.la
-vmware_guestd_LDADD += ../lib/vixTools/libVixTools.la
-vmware_guestd_LDADD += ../lib/vmBackupLib/libVmBackupLib.la
-vmware_guestd_LDADD += ../lib/vmCheck/libVmCheck.la
-vmware_guestd_LDADD += ../lib/vmSignal/libVmSignal.la
-vmware_guestd_LDADD += ../lib/wiper/libWiper.la
-# In the absence of the linker options --start-group and --end-group (which
-# can't be put in LDADD), we need to bring the following libraries out of the
-# alphabetical order so their symbols are properly resolved.
-vmware_guestd_LDADD += ../lib/dict/libDict.la
-vmware_guestd_LDADD += ../lib/dynxdr/libDynxdr.la
-vmware_guestd_LDADD += ../lib/hgfs/libHgfs.la
-vmware_guestd_LDADD += ../lib/message/libMessage.la
-vmware_guestd_LDADD += ../lib/unicode/libUnicode.la
-vmware_guestd_LDADD += ../lib/misc/libMisc.la
-vmware_guestd_LDADD += ../lib/foundryMsg/libFoundryMsg.la
-vmware_guestd_LDADD += ../lib/auth/libAuth.la
-vmware_guestd_LDADD += ../lib/panicDefault/libPanicDefault.la
-vmware_guestd_LDADD += ../lib/panic/libPanic.la
-vmware_guestd_LDADD += ../lib/stubs/libStubs.la
-if SOLARIS
- HGFS_BD = ../lib/hgfsBd/libHgfsBd.la
-else
- HGFS_BD =
-endif
-vmware_guestd_LDADD += $(HGFS_BD)
-vmware_guestd_LDADD += @GUESTD_LDADD@
-
-vmware_guestd_SOURCES =
-vmware_guestd_SOURCES += debugStdio.c
-vmware_guestd_SOURCES += foreignVMToolsDaemon.c
-vmware_guestd_SOURCES += foreignVMToolsNetworking.c
-vmware_guestd_SOURCES += $(top_srcdir)/services/plugins/vix/foundryToolsDaemon.c
-vmware_guestd_SOURCES += main.c
-vmware_guestd_SOURCES += toolsDaemon.c
-
-if HAVE_ICU
- vmware_guestd_LDADD += @ICU_LIBS@
- vmware_guestd_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXX) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-else
- vmware_guestd_LINK = $(LINK)
-endif
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-
-/*
- * debug.c --
- *
- * Platform specific debug routines
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#if defined(_WIN32) && defined(_MSC_VER)
-# include <windows.h>
-#endif
-#if defined(N_PLAT_NLM)
-# include "vmwtool.h"
-#endif
-
-
-#include "vmware.h"
-#include "debug.h"
-#include "util.h"
-#include "str.h"
-#include "fileIO.h"
-#include "file.h"
-#include "system.h"
-#include "unicode.h"
-
-static char debugFile[FILE_MAXPATH] = {0};
-static Bool debugEnabled = FALSE;
-static const char *debugPrefix = NULL;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug_Set --
- *
- * Enable/Disable debugging output
- *
- * Result
- * None.
- *
- * Side-effects
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Debug_Set(Bool enable, // IN
- const char *prefix) // IN
-{
- debugEnabled = enable;
- debugPrefix = prefix;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug_EnableToFile --
- *
- * Enable debugging output to the given file. If backup is TRUE, will rename
- * existing file to file.old and start logging to a new file. Only daemon
- * should set backup flag then will do backup for each reboot.
- *
- * Result
- * None.
- *
- * Side-effects
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Debug_EnableToFile(const char *file, // IN
- Bool backup) // IN
-{
- if (backup && file && File_Exists(file)) {
- /* Back up existing log file. */
- char *bakFile = Str_Asprintf(NULL, "%s.old", file);
- if (bakFile &&
- !File_IsDirectory(bakFile) &&
- 0 == File_UnlinkIfExists(bakFile)) { // remove old back up file.
- File_Rename(file, bakFile);
- }
- free(bakFile);
- }
- if (file) {
- Str_Sprintf(debugFile, sizeof debugFile, "%s", file);
- debugEnabled = TRUE;
- } else {
- debugFile[0] = '\0';
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug_IsEnabled --
- *
- * Is debugging output enabled?
- *
- * Result
- * TRUE/FALSE
- *
- * Side-effects
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-Debug_IsEnabled(void)
-{
- return debugEnabled;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DebugToFile --
- *
- * Print a string to the given file. This opens & closes the file
- * handle each time it is called so it will significantly
- * slow down the calling program. This is done so that the file
- * can be opened & read while the program is running.
- *
- * Results:
- * None.
- *
- * Side effects:
- * DebugToFile is turned off if there was an error opening the file.
- *
- *-----------------------------------------------------------------------------
- */
-
-static
-void DebugToFile(const char *str) // IN
-{
-#ifndef _CONSOLE
- FileIOResult fr;
- FileIODescriptor fd;
- size_t bytesWritten;
- Unicode timePrefix;
- const char *timePrefixUtf8;
- char debugFileShadow;
-
- ASSERT(debugFile[0] != 0);
-
- FileIO_Invalidate(&fd);
-
- fr = FileIO_Open(&fd, debugFile, FILEIO_OPEN_ACCESS_WRITE,
- FILEIO_OPEN_CREATE);
- debugFileShadow = debugFile[0];
- debugFile[0] = '\0';
- if (fr != FILEIO_SUCCESS) {
- Warning("---Error opening file '%s'.\n", debugFile);
- goto done;
- }
-
- /*
- * XXX: Writing the date/time prefix in UTF-8 and the rest of the string in
- * an unspecified encoding is rather broken, but it'll have to do until the
- * rest of the Tools are made internationalization-safe.
- */
- timePrefix = System_GetTimeAsString();
- if (timePrefix == NULL) {
- Warning("---Error getting formatted time string.\n");
- goto close;
- }
- timePrefixUtf8 = UTF8(timePrefix);
- ASSERT(timePrefixUtf8);
-
- FileIO_Seek(&fd, 0, FILEIO_SEEK_END);
- fr = FileIO_Write(&fd, timePrefixUtf8, strlen(timePrefixUtf8), &bytesWritten);
- fr = FileIO_Write(&fd, str, strlen(str), &bytesWritten);
- Unicode_Free(timePrefix);
- if (fr != FILEIO_SUCCESS) {
- Warning("---Error writing to file '%s'.\n", debugFile);
- }
-
- close:
- FileIO_Close(&fd);
-
- done:
- debugFile[0] = debugFileShadow;
- return;
-#endif // _CONSOLE
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug --
- *
- * If debugging is enabled, output debug information
- *
- * Result
- * None.
- *
- * Side-effects
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Debug(char const *fmt, // IN: Format string
- ...) // IN: Arguments
-{
- va_list args;
- char *str;
- char *msg;
-
- if (debugEnabled == FALSE) {
- return;
- }
-
- va_start(args, fmt);
- msg = Str_Vasprintf(NULL, fmt, args);
- va_end(args);
-
- str = Str_Asprintf(NULL, "[%s]: %s", debugPrefix ? debugPrefix : "NULL", msg);
- free(msg);
-
-#ifdef N_PLAT_NLM
- OutputToScreenWithAttribute(VMwareScreen, BOLD_RED, "%s", str);
-#else
-#ifdef _WIN32
- OutputDebugString(str);
-#endif
-#if !defined(_WIN32) || defined(_CONSOLE)
- fputs(str, stderr);
-#endif
-#endif
- if (debugFile[0] != '\0') {
- DebugToFile(str);
- }
-
- free(str);
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * foreignVMToolsDaemon.c --
- *
- * This implements the Vix tools using a socket to connect to the tools
- * from a client. This also assumes there is no VMX process, so the
- * tools takes commands directly from the client over the socket.
- *
- * In a VMware VM:
- * Client ---socket---> VMX ---backdoor---> Tools
- *
- * In a foreign VM:
- * Client ---socket---> Tools
- *
- * So, this code performs operations on behalf of the VMX and the tools.
- * The tools functions are all implemented by the vixTools library, which
- * is the same code that runs in the VMware tools. This module then handles
- * socket communication and does functions that would otherwise be done by
- * the VMX.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdarg.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <MSWSock.h>
-#else
-#include <sys/types.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#if defined(__FreeBSD__) || defined(sun) || defined(__APPLE__)
-#include <unistd.h>
-#else
-#include <linux/unistd.h>
-#endif
-#endif
-
-#include "vmware.h"
-#include "vm_version.h"
-#include "vm_app.h"
-#include "message.h"
-#include "eventManager.h"
-#include "debug.h"
-#include "util.h"
-#include "strutil.h"
-#include "str.h"
-#include "err.h"
-#include "hostinfo.h"
-#include "guest_os.h"
-#include "conf.h"
-#include "base64.h"
-#include "hgfsServer.h"
-#include "hgfs.h"
-#include "system.h"
-#include "codeset.h"
-
-#include "vixOpenSource.h"
-#include "syncEvent.h"
-#include "foundryThreads.h"
-#include "vixCommands.h"
-#include "foreignVMToolsDaemon.h"
-
-#include "vixTools.h"
-
-
-VixLockType globalLock;
-static struct FoundryWorkerThread *selectThread;
-static DblLnkLst_Links *gEventQueue;
-
-ForeignVMToolsConnection *activeConnectionList = NULL;
-ForeignVMToolsCommand *globalCommandList = NULL;
-
-static struct GuestApp_Dict *configDictionary = NULL;
-
-static Bool ForeignToolsIsCommandAlive(ForeignVMToolsCommand *asyncCommand);
-
-static ForeignVMToolsCommand *ForeignToolsGetActiveCommand(const char *name);
-
-static void ForeignToolsSendRunProgramResponse(const char *requestName,
- VixError resultErr,
- int exitCode,
- int64 pid,
- void *clientData);
-
-static VixError ForeignToolsGetUserCredentialForGuest(ForeignVMToolsConnection *connectionState,
- ForeignVMToolsCommand *commandState);
-
-static VixError ForeignToolsGetProperties(ForeignVMToolsCommand *asyncCommand,
- VixMsgTrivialRequest *requestMsg);
-
-static VixError ForeignToolsSetProperties(ForeignVMToolsCommand *asyncCommand,
- VixMsgSetVMStateRequest *requestMsg);
-
-static VixError ForeignToolsGetToolsState(ForeignVMToolsCommand *asyncCommand,
- VixMsgTrivialRequest *requestMsg);
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignTools_Initialize --
- *
- * Start a worker thread.
- *
- * Results:
- * FoundryWorkerThread *
- *
- * Side effects:
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-ForeignTools_Initialize(GuestApp_Dict *configDictionaryParam, // IN
- DblLnkLst_Links *eventQueue) // IN
-{
- VixError err = VIX_OK;
- Bool success = TRUE;
-
- MessageStub_RegisterTransport();
- gEventQueue = eventQueue;
-
- /*
- * Initialize the limited global state that protects us when
- * client applications explicitly pump events.
- */
- err = VIX_INIT_LOCK(&globalLock);
- if (VIX_OK != err) {
- success = FALSE;
- goto abort;
- }
-
- if (NULL == configDictionaryParam) {
- success = FALSE;
- goto abort;
- }
- configDictionary = configDictionaryParam;
-
- VixTools_SetConsoleUserPolicy(TRUE); // allowConsoleUserOpsParam
- VixTools_SetRunProgramCallback(ForeignToolsSendRunProgramResponse, NULL);
-
- success = ForeignTools_InitializeNetworking();
- if (!success) {
- goto abort;
- }
-
- /*
- * Start the worker threads that will pump poll.
- */
- selectThread = FoundryThreads_StartThread(ForeignToolsSelectLoop, NULL);
- if (NULL == selectThread) {
- goto abort;
- }
-
- return(TRUE);
-
-abort:
- return(FALSE);
-} // ForeignTools_Initialize
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignTools_Shutdown --
- *
- * Shutdown a thread and destroys its thread state.
- *
- * Results:
- * None.
- *
- * Side effects:
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ForeignTools_Shutdown(void)
-{
- /*
- * Tell the select thread to exit and wait for it to stop.
- */
- selectThread->stopThread = TRUE;
- ForeignToolsWakeSelectThread();
- if (NULL != selectThread) {
- FoundryThreads_StopThread(selectThread);
- selectThread = NULL;
- }
-
- /*
- * Close every connection.
- */
- VIX_ENTER_LOCK(&globalLock);
- while (NULL != activeConnectionList) {
- ForeignToolsCloseConnection(activeConnectionList, SHUTDOWN_FOR_SYSTEM_SHUTDOWN);
- }
- VIX_LEAVE_LOCK(&globalLock);
-
- /*
- * Shut down the work queue.
- */
- VIX_DELETE_LOCK(&globalLock);
-} // ForeignTools_Shutdown
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsIsCommandAlive --
- *
- * Returns TRUE if ForeignVMToolsCommand is still in the list of
- * active commands. Otherwise, return FALSE.
- *
- * Results:
- * None.
- *
- * Side effects:
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-ForeignToolsIsCommandAlive(ForeignVMToolsCommand *asyncCommand) // IN
-{
- ForeignVMToolsCommand *command;
- ForeignVMToolsCommand *nextCommand;
- Bool isAlive = FALSE;
-
- if (NULL == asyncCommand) {
- goto abort;
- }
-
- VIX_ENTER_LOCK(&globalLock);
-
- command = globalCommandList;
- while (NULL != command) {
- nextCommand = command->next;
- if (command == asyncCommand) {
- isAlive = TRUE;
- break;
- }
- command = nextCommand;
- }
-
- VIX_LEAVE_LOCK(&globalLock);
-
-abort:
- return(isAlive);
-} // ForeignToolsIsCommandAlive
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsDiscardCommand --
- *
- * Record that we are executing an async command.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsDiscardCommand(ForeignVMToolsCommand *command) // IN
-{
- ForeignVMToolsCommand *targetCommand;
- ForeignVMToolsCommand *prevCommand;
-
- if ((NULL == command) || (NULL == command->connection)) {
- return;
- }
-
- VIX_ENTER_LOCK(&globalLock);
-
- targetCommand = globalCommandList;
- prevCommand = NULL;
- while (NULL != targetCommand) {
- if (targetCommand == command) {
- break;
- }
- prevCommand = targetCommand;
- targetCommand = targetCommand->next;
- }
-
- /*
- * If the command is not in the active list, then somebody else
- * already freed it. Do not delete it again.
- */
- if (NULL == targetCommand) {
- goto abort;
- }
-
- if (NULL != prevCommand) {
- prevCommand->next = targetCommand->next;
- } else {
- globalCommandList = targetCommand->next;
- }
-
- free(command->responseBody);
- free(command->guestUserNamePassword);
- free(command->obfuscatedGuestUserNamePassword);
- free(command);
-
-abort:
- VIX_LEAVE_LOCK(&globalLock);
-} // ForeignToolsDiscardCommand
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsGetActiveCommand --
- *
- * This gets the named active state.
- *
- * Results:
- * The named active state.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-ForeignVMToolsCommand *
-ForeignToolsGetActiveCommand(const char *name) // IN
-{
- ForeignVMToolsCommand *command = NULL;
-
- /*
- * Look for the test that corresponds to this name.
- */
- VIX_ENTER_LOCK(&globalLock);
-
- command = globalCommandList;
- while (NULL != command) {
- if (0 == Str_Strcasecmp(name, command->asyncOpName)) {
- break;
- }
-
- command = command->next;
- }
-
- VIX_LEAVE_LOCK(&globalLock);
-
- return command;
-} // ForeignToolsGetActiveCommand
-
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsSendRunProgramResponse --
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsSendRunProgramResponse(const char *requestName, // IN
- VixError resultErr, // IN
- int exitCode, // IN
- int64 pid, // IN
- void *clientData) // IN
-{
- VixError err = VIX_OK;
- int additionalError = 0;
- ForeignVMToolsCommand *asyncCommand = NULL;
- VmTimeType programStopTime;
- VmTimeType deltaTime = 0;
- VixMsgRunProgramResponse responseMessage;
-
- Hostinfo_GetTimeOfDay(&programStopTime);
-
- asyncCommand = ForeignToolsGetActiveCommand(requestName);
- if (NULL == asyncCommand) {
- return;
- }
- /*
- * If all we wanted to do was start the program, then we are
- * done.
- */
- if (asyncCommand->runProgramOptions & VIX_RUNPROGRAM_RETURN_IMMEDIATELY) {
- return;
- }
-
- err = resultErr;
-
- /*
- * Find how long the program was running. Convert to seconds,
- * and report the result in VMDB.
- */
- deltaTime = programStopTime - asyncCommand->programStartTime;
- deltaTime = deltaTime / 1000000;
-
- responseMessage.exitCode = exitCode;
- responseMessage.deltaTime = deltaTime;
- responseMessage.pid = pid;
- responseMessage.stdOutLength = 0;
- responseMessage.stdErrLength = 0;
-
- ForeignToolsSendResponseUsingTotalMessage(asyncCommand->connection,
- &(asyncCommand->requestHeader),
- sizeof responseMessage,
- &responseMessage,
- err,
- additionalError,
- VIX_RESPONSE_EXTENDED_RESULT_V1);
- ForeignToolsDiscardCommand(asyncCommand);
-} // ForeignToolsSendRunProgramResponse
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsGetUserCredentialForGuest --
- *
- * Get the credentials we will pass into the guest.
- * These may be passed in with the original command request, or else we
- * may use some default values.
- *
- * This also does limited checking, mainly to see if any credentials are
- * even provided. It does NOT check to see if a user/name password is valid,
- * or if a particular user is authorized for some operation. That will
- * be done later in the guest when we actually execute each operation.
- *
- * This leaves the actual credentials for this command packaged in
- * commandState->obfuscatedGuestUserNamePassword
- *
- * Results:
- * VixError
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-VixError
-ForeignToolsGetUserCredentialForGuest(ForeignVMToolsConnection *connectionState, // IN
- ForeignVMToolsCommand *commandState) // IN
-{
- VixError err = VIX_OK;
- //CryptoError cryptoErr = CRYPTO_ERROR_SUCCESS;
- Bool success;
- char *guestUserName = NULL;
- char *guestPassword = NULL;
- char *namePasswordMessage = NULL;
- char *endCredential;
- char *encryptedNamePassword = NULL;
- size_t encryptedNamePasswordLength = 0;
- char *decryptedBuffer = NULL;
- size_t decryptedBufferLength = 0;
- VixCommandNamePassword *guestUserNamePassword;
- VixCommandNamePassword newUserNamePassword;
- size_t newCredentialsLength;
- size_t newMessageLength;
- char *newNamePasswordBuffer;
- //CryptoKeyedHash *keyedHash;
-
- /*
- * If there was an optional userName and password sent, then parse it now.
- */
- if (VIX_USER_CREDENTIAL_NAME_PASSWORD == commandState->requestHeader.userCredentialType) {
- if (commandState->requestHeader.commonHeader.credentialLength <= 0) {
- err = VIX_E_INVALID_MESSAGE_HEADER;
- goto abort;
- }
-
- namePasswordMessage = connectionState->completeRequest
- + commandState->requestHeader.commonHeader.headerLength
- + commandState->requestHeader.commonHeader.bodyLength;
- endCredential = namePasswordMessage
- + commandState->requestHeader.commonHeader.credentialLength;
- /*
- * Make sure this is a valid NULL-terminated C string.
- */
- if (*(endCredential - 1)) {
- err = VIX_E_INVALID_MESSAGE_HEADER;
- goto abort;
- }
-
- success = Base64_EasyDecode(namePasswordMessage,
- (uint8 **) &encryptedNamePassword,
- &encryptedNamePasswordLength);
- if (!success) {
- err = VIX_E_INVALID_MESSAGE_HEADER;
- goto abort;
- }
-
-#if 0
- cryptoErr = CryptoKeyedHash_FromString(CryptoKeyedHashName_HMAC_SHA_1,
- &keyedHash);
- if (CryptoError_IsFailure(cryptoErr)) {
- err = Vix_TranslateCryptoError(cryptoErr);
- goto abort;
- }
-
- cryptoErr = CryptoKey_DecryptWithMAC(connectionState->sessionKey,
- keyedHash,
- (uint8 *) encryptedNamePassword,
- encryptedNamePasswordLength,
- (uint8 **) &decryptedBuffer,
- &decryptedBufferLength);
- if (CryptoError_IsFailure(cryptoErr)) {
- err = Vix_TranslateCryptoError(cryptoErr);
- goto abort;
- }
-#else
- decryptedBuffer = encryptedNamePassword;
- decryptedBufferLength = encryptedNamePasswordLength;
-#endif
-
- /*
- * Get the name/password fields from the credential data structure.
- */
- guestUserNamePassword = (VixCommandNamePassword *) decryptedBuffer;
- guestUserName = (char *) guestUserNamePassword;
- guestUserName += sizeof(VixCommandNamePassword);
- guestPassword = guestUserName;
- guestPassword += guestUserNamePassword->nameLength + 1;
-
- /*
- * If the client sent a valid userName/password, then this is OK.
- * Send it on to the tools and they will check permissions.
- * Allow an empty password string, that may be valid for some accounts.
- */
- if ((NULL == guestUserName) || !(guestUserName[0])) {
- err = VIX_E_GUEST_USER_PERMISSIONS;
- goto abort;
- }
-
- commandState->obfuscatedCredentialType = commandState->requestHeader.userCredentialType;
- /////////////////////////////////////////////////////////////////////////////
- } else if ((VIX_USER_CREDENTIAL_ANONYMOUS == commandState->requestHeader.userCredentialType)
- || (VIX_USER_CREDENTIAL_NONE == commandState->requestHeader.userCredentialType)) {
- err = VIX_E_MISSING_ANON_GUEST_ACCOUNT;
- goto abort;
- /////////////////////////////////////////////////////////////////////////////
- } else if (VIX_USER_CREDENTIAL_ROOT == commandState->requestHeader.userCredentialType) {
- err = VIX_E_ROOT_GUEST_OPERATIONS_PROHIBITED;
- goto abort;
- /////////////////////////////////////////////////////////////////////////////
- } else if (VIX_USER_CREDENTIAL_CONSOLE_USER == commandState->requestHeader.userCredentialType) {
- //<> For debug only. I need this until I package the tools as
- // an NT service. Otherwise, I cannot run a program.
- //<><>err = VIX_E_CONSOLE_GUEST_OPERATIONS_PROHIBITED;
- //<><>goto abort;
- } else {
- err = VIX_E_UNRECOGNIZED_COMMAND;
- goto abort;
- }
-
- /*
- * Now, package the name/password to be sent to the guest.
- */
- commandState->obfuscatedGuestUserNamePassword
- = VixMsg_ObfuscateNamePassword(guestUserName, guestPassword);
-
- newCredentialsLength = sizeof(VixCommandNamePassword)
- + strlen(commandState->obfuscatedGuestUserNamePassword) + 1;
-
- newMessageLength = commandState->requestHeader.commonHeader.totalMessageLength
- - commandState->requestHeader.commonHeader.credentialLength
- + newCredentialsLength;
-
- connectionState->completeRequest = Util_SafeRealloc(connectionState->completeRequest,
- newMessageLength);
- if (NULL != guestUserName) {
- newUserNamePassword.nameLength = strlen(guestUserName);
- } else {
- newUserNamePassword.nameLength = 0;
- }
- if (NULL != guestPassword) {
- newUserNamePassword.passwordLength = strlen(guestPassword);
- } else {
- newUserNamePassword.passwordLength = 0;
- }
- newNamePasswordBuffer = connectionState->completeRequest
- + commandState->requestHeader.commonHeader.headerLength
- + commandState->requestHeader.commonHeader.bodyLength;
-
- memcpy(newNamePasswordBuffer,
- &newUserNamePassword,
- sizeof(newUserNamePassword));
- newNamePasswordBuffer += sizeof(newUserNamePassword);
- memcpy(newNamePasswordBuffer,
- commandState->obfuscatedGuestUserNamePassword,
- strlen(commandState->obfuscatedGuestUserNamePassword) + 1);
-
- commandState->requestHeader.commonHeader.totalMessageLength = newMessageLength;
- commandState->requestHeader.commonHeader.credentialLength = newCredentialsLength;
-
- connectionState->requestHeader.commonHeader.totalMessageLength = newMessageLength;
- connectionState->requestHeader.commonHeader.credentialLength = newCredentialsLength;
-
-
-abort:
- free(encryptedNamePassword);
-#if 0
- Crypto_Free(decryptedBuffer, decryptedBufferLength);
-#endif
-
- return(err);
-} // ForeignToolsGetUserCredentialForGuest
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsGetProperties --
- *
- * Results:
- * VixError
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-VixError
-ForeignToolsGetProperties(ForeignVMToolsCommand *asyncCommand, // IN
- VixMsgTrivialRequest *requestMsg) // IN
-{
- VixError err = VIX_OK;
- VixPropertyListImpl propList;
- char *serializedBufferBody = NULL;
- size_t serializedBufferLength = 0;
- char *responseMessage = NULL;
- size_t responseMessageLength = 0;
- int guestOSID;
- int guestOSFamily = GUEST_OS_FAMILY_ANY;
-
- guestOSID = 0; // GuestOS_GetOSID(NULL);
-
-
- VixPropertyList_Initialize(&propList);
-
- err = VixPropertyList_SetInteger(&propList,
- VIX_PROPERTY_VM_TOOLS_STATE,
- VIX_TOOLSSTATE_RUNNING);
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_VMX_VERSION,
- "Foreign VM Tools");
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_FOREIGN_VM_TOOLS_VERSION,
- VIX_FOREIGN_VM_TOOLS_VMX_VERSION_STRING);
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_VMX_PRODUCT_NAME,
- PRODUCT_NAME);
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetInteger(&propList,
- VIX_PROPERTY_VMX_VIX_FEATURES,
- VIX_TOOLSFEATURE_SUPPORT_GET_HANDLE_STATE);
- if (VIX_OK != err) {
- goto abort;
- }
-
- /*
- * *****************************************
- * Now, fill in default values for the tools.
- * Later, if the tools are running, they will have a chance to
- * provide correct values.
- */
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_GUEST_TOOLS_PRODUCT_NAM,
- "");
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_GUEST_TOOLS_VERSION,
- "");
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetInteger(&propList,
- VIX_PROPERTY_GUEST_TOOLS_API_OPTIONS,
- 0);
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetInteger(&propList,
- VIX_PROPERTY_GUEST_OS_FAMILY,
- guestOSFamily);
-
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_GUEST_NAME,
- "");
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_GUEST_POWER_OFF_SCRIPT,
- "");
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_GUEST_POWER_ON_SCRIPT,
- "");
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_GUEST_SUSPEND_SCRIPT,
- "");
- if (VIX_OK != err) {
- goto abort;
- }
- err = VixPropertyList_SetString(&propList,
- VIX_PROPERTY_GUEST_RESUME_SCRIPT,
- "");
- if (VIX_OK != err) {
- goto abort;
- }
-
- /*
- * Serialize the property list to buffer
- */
- err = VixPropertyList_Serialize(&propList,
- FALSE,
- &serializedBufferLength,
- &serializedBufferBody);
- if (VIX_OK != err) {
- goto abort;
- }
-
- responseMessageLength = sizeof(VixMsgGetVMStateResponse)
- + serializedBufferLength;
- responseMessage = Util_SafeMalloc(responseMessageLength);
- memcpy(responseMessage + sizeof(VixMsgGetVMStateResponse),
- serializedBufferBody,
- serializedBufferLength);
- ((VixMsgGetVMStateResponse *) responseMessage)->bufferSize = serializedBufferLength;
-
- ForeignToolsSendResponseUsingTotalMessage(asyncCommand->connection,
- &(asyncCommand->requestHeader),
- responseMessageLength,
- responseMessage,
- err,
- 0, // additionalError,
- 0); // responseFlags
- ForeignToolsDiscardCommand(asyncCommand);
-
- /*
- * ForeignToolsSendResponseUsingTotalMessage owns responseMessage now,
- * and it will deallocate it.
- */
- responseMessage = NULL;
-
-abort:
- free(responseMessage);
- free(serializedBufferBody);
- VixPropertyList_RemoveAllWithoutHandles(&propList);
-
- return err;
-} // ForeignToolsGetProperties
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsSetProperties --
- *
- * Results:
- * VixError
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-VixError
-ForeignToolsSetProperties(ForeignVMToolsCommand *asyncCommand, // IN
- VixMsgSetVMStateRequest *requestMsg) // IN
-{
- VixError err = VIX_OK;
- VixPropertyListImpl propList;
- size_t serializedBufferLength = 0;
- char *serializedBuffer = NULL;
-
- /*
- * Do some validation
- */
- if ((NULL == asyncCommand)
- || (NULL == requestMsg)
- || (0 > requestMsg->bufferSize)) {
- err = VIX_E_INVALID_ARG;
- goto abort;
- }
-
- serializedBufferLength = requestMsg->bufferSize;
- serializedBuffer = ((char*)requestMsg + sizeof(*requestMsg));
-
- /*
- * Create a temporary property list and deserialize the buffer into.
- */
- err = VixPropertyList_Deserialize(&propList,
- serializedBuffer,
- serializedBufferLength);
- if (VIX_OK != err) {
- goto abort;
- }
-
- /*
- * To Do: <>
- * Change any VMX properties here.
- */
-
-abort:
- VixPropertyList_RemoveAllWithoutHandles(&propList);
-
- return err;
-} // ForeignToolsSetProperties
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsGetToolsState --
- *
- * Results:
- * VixError
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-VixError
-ForeignToolsGetToolsState(ForeignVMToolsCommand *asyncCommand, // IN
- VixMsgTrivialRequest *requestMsg) // IN
-{
- VixError err = VIX_OK;
- VixPropertyListImpl propList;
- char *decodedStr = NULL;
- size_t decodedLength;
- Bool success;
- char *serializedBufferBody = NULL;
- size_t serializedBufferLength = 0;
- Bool deleteResultValue = FALSE;
- char *base64Buffer = NULL;
- size_t base64BufferLength;
- char *responseMessage = NULL;
- size_t responseMessageLength = 0;
-
- VixPropertyList_Initialize(&propList);
-
- err = VixTools_ProcessVixCommand((VixCommandRequestHeader *) asyncCommand,
- asyncCommand->asyncOpName,
- 1024 * 1024, // maxResultBufferSize,
- &configDictionary,
- gEventQueue,
- &base64Buffer,
- &base64BufferLength,
- &deleteResultValue);
- if (VIX_OK != err) {
- goto abort;
- }
-
- /*
- * If we got a string back from the guest, then decode it and
- * convert it into a list of properties.
- */
- if (NULL != base64Buffer) {
- decodedStr = Util_SafeMalloc(base64BufferLength);
- success = Base64_Decode(base64Buffer,
- decodedStr,
- base64BufferLength,
- &decodedLength);
- if (success) {
- err = VixPropertyList_Deserialize(&propList, decodedStr, decodedLength);
- err = VIX_OK;
- }
-
- (void) VixPropertyList_SetInteger(&propList,
- VIX_PROPERTY_VM_TOOLS_STATE,
- VIX_TOOLSSTATE_RUNNING);
- } else { // if (NULL == base64Buffer)
- (void) VixPropertyList_SetInteger(&propList,
- VIX_PROPERTY_VM_TOOLS_STATE,
- VIX_TOOLSSTATE_NOT_INSTALLED);
- }
-
- /*
- * Serialize the property list to buffer
- */
- err = VixPropertyList_Serialize(&propList,
- FALSE,
- &serializedBufferLength,
- &serializedBufferBody);
- if (VIX_OK != err) {
- goto abort;
- }
-
- responseMessageLength = sizeof(VixMsgGetVMStateResponse)
- + serializedBufferLength;
- responseMessage = Util_SafeMalloc(responseMessageLength);
- memcpy(responseMessage + sizeof(VixMsgGetVMStateResponse),
- serializedBufferBody,
- serializedBufferLength);
- ((VixMsgGetVMStateResponse *) responseMessage)->bufferSize = serializedBufferLength;
-
- ForeignToolsSendResponseUsingTotalMessage(asyncCommand->connection,
- &(asyncCommand->requestHeader),
- responseMessageLength,
- responseMessage,
- err,
- 0, // additionalError,
- 0); // responseFlags
- ForeignToolsDiscardCommand(asyncCommand);
-
- /*
- * VMAutomation_SendResponseUsingTotalMessage owns responseMessage now,
- * and it will deallocate it.
- */
- responseMessage = NULL;
-
-abort:
- VixPropertyList_RemoveAllWithoutHandles(&propList);
- free(decodedStr);
- free(serializedBufferBody);
- free(responseMessage);
-
- return err;
-} // ForeignToolsGetToolsState
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsProcessMessage --
- *
- * Calls the correct handler for a particular message type,
- * and determines whether to queue more receives.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsProcessMessage(ForeignVMToolsConnection *connectionState) //IN
-{
- VixError err = VIX_OK;
- ForeignVMToolsCommand *commandState = NULL;
- uint32 additionalError = 0;
- Bool sendResponse = FALSE;
- Bool deleteResultValue = FALSE;
- char *dummyResponse;
- size_t dummyResponseLength;
-
- ASSERT(NULL != connectionState);
-
- /*
- * Allocate state for the command.
- */
- commandState = Util_SafeCalloc(1, sizeof *commandState);
- commandState->connection = connectionState;
- commandState->requestHeader = connectionState->requestHeader;
- commandState->guestCredentialType = connectionState->requestHeader.userCredentialType;
- commandState->guestUserNamePassword = NULL;
- commandState->obfuscatedGuestUserNamePassword = NULL;
- commandState->obfuscatedCredentialType = 0;
- commandState->runProgramOptions = 0;
- commandState->responseBody = NULL;
- commandState->responseBodyLength = 0;
-
- VIX_ENTER_LOCK(&globalLock);
- commandState->next = globalCommandList;
- globalCommandList = commandState;
- VIX_LEAVE_LOCK(&globalLock);
-
- switch (connectionState->requestHeader.opCode) {
- ///////////////////////////////////
- case VIX_COMMAND_GET_HANDLE_STATE:
- err = ForeignToolsGetProperties(commandState,
- (VixMsgTrivialRequest *) connectionState->completeRequest);
- break;
-
- ///////////////////////////////////
- case VIX_COMMAND_INSTALL_TOOLS:
- case VIX_COMMAND_WAIT_FOR_TOOLS:
- err = VIX_OK;
- sendResponse = TRUE;
- break;
-
- ///////////////////////////////////
- case VIX_COMMAND_GET_DISK_PROPERTIES:
- case VIX_COMMAND_CAPTURE_SCREEN:
- case VIX_COMMAND_MOUSE_EVENTS:
- case VIX_COMMAND_KEYSTROKES:
- case VIX_COMMAND_LIST_USB_DEVICES:
- err = VIX_E_NOT_SUPPORTED;
- break;
-
- ///////////////////////////////////
- case VIX_CREATE_SESSION_KEY_COMMAND:
- err = VIX_E_NOT_SUPPORTED;
- break;
-
- ///////////////////////////////////
- case VIX_COMMAND_SET_HANDLE_STATE:
- err = ForeignToolsSetProperties(commandState,
- (VixMsgSetVMStateRequest *) (connectionState->completeRequest));
- sendResponse = TRUE;
- break;
-
- ///////////////////////////////////
- case VIX_COMMAND_RUN_PROGRAM:
- err = ForeignToolsGetUserCredentialForGuest(connectionState, commandState);
- if (VIX_OK != err) {
- goto abort;
- }
-
- Hostinfo_GetTimeOfDay(&(commandState->programStartTime));
- Str_Snprintf(commandState->asyncOpName,
- sizeof(commandState->asyncOpName),
- "%p",
- commandState);
- commandState->responseBody = NULL;
-
- err = VixTools_ProcessVixCommand((VixCommandRequestHeader *) connectionState->completeRequest,
- commandState->asyncOpName,
- 1024 * 1024, // maxResultBufferSize,
- &configDictionary,
- gEventQueue,
- &dummyResponse,
- &dummyResponseLength,
- &deleteResultValue);
-
- /*
- * We don't complete the command until the program exits.
- */
- commandState->responseBody = NULL;
- commandState->responseBodyLength = 0;
- break;
-
-#if 0
- ///////////////////////////////////
- //<><><>
- // I can add these.
- case VIX_COMMAND_VM_POWEROFF:
- case VIX_COMMAND_VM_RESET:
- case VIX_COMMAND_RELOAD_VM:
- break;
-
- ///////////////////////////////////
- //<><><>
- // These will not be supported.
- case VIX_COMMAND_VM_SUSPEND:
- case VIX_COMMAND_SET_NIC_BANDWIDTH:
- case VIX_COMMAND_UPGRADE_VIRTUAL_HARDWARE:
- case VIX_COMMAND_CREATE_RUNNING_VM_SNAPSHOT:
- case VIX_COMMAND_CONSOLIDATE_RUNNING_VM_SNAPSHOT:
- break;
-#endif
-
- ///////////////////////////////////
- case VIX_COMMAND_GET_TOOLS_STATE:
- err = ForeignToolsGetToolsState(commandState,
- (VixMsgTrivialRequest *) (connectionState->completeRequest));
- break;
-
- ////////////////////////////////////
- case VIX_COMMAND_CHECK_USER_ACCOUNT:
- case VIX_COMMAND_LOGOUT_IN_GUEST:
- err = ForeignToolsGetUserCredentialForGuest(connectionState, commandState);
- if (VIX_OK != err) {
- goto abort;
- }
-
- if (VIX_USER_CREDENTIAL_NAME_PASSWORD
- == commandState->requestHeader.userCredentialType) {
- err = VixTools_ProcessVixCommand((VixCommandRequestHeader *) connectionState->completeRequest,
- commandState->asyncOpName,
- 1024 * 1024, // maxResultBufferSize,
- &configDictionary,
- gEventQueue,
- &(commandState->responseBody),
- &(commandState->responseBodyLength),
- &deleteResultValue);
- } else {
- commandState->responseBody = NULL;
- commandState->responseBodyLength = 0;
- }
-
- sendResponse = TRUE;
- break;
-
-
- ///////////////////////////////////
- // By default, most tools commands do require authentication.
- default:
- err = ForeignToolsGetUserCredentialForGuest(connectionState, commandState);
- if (VIX_OK != err) {
- goto abort;
- }
-
- err = VixTools_ProcessVixCommand((VixCommandRequestHeader *) connectionState->completeRequest,
- commandState->asyncOpName,
- 1024 * 1024, // maxResultBufferSize,
- &configDictionary,
- gEventQueue,
- &(commandState->responseBody),
- &(commandState->responseBodyLength),
- &deleteResultValue);
-
- sendResponse = TRUE;
- break;
- } // switch
-
-
-abort:
- if ((VIX_OK != err) || (sendResponse)) {
- if (ForeignToolsIsCommandAlive(commandState)) {
- ForeignToolsSendResponse(connectionState,
- &(connectionState->requestHeader),
- commandState->responseBodyLength,
- commandState->responseBody,
- err,
- additionalError,
- 0); // responseFlags
-
- if (!deleteResultValue) {
- commandState->responseBody = NULL;
- commandState->responseBodyLength = 0;
- }
-
- ForeignToolsDiscardCommand(commandState);
- }
- }
-} // ForeignToolsProcessMessage
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-
-/*
- * foreignVMToolsDaemon.h --
- *
- *
- */
-
-#ifndef __FOREIGN_VM_TOOLS_DAEMON_H__
-#define __FOREIGN_VM_TOOLS_DAEMON_H__
-
-struct ForeignVMToolsConnection;
-
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Locks --
- *
- * This is the lock for each handle. We may have thousands of handles,
- * so these locks must be lightweight. SyncRecMutex creates a pair
- * of file handles on Linux, so it doesn't scale. That's ok, since we
- * don't need all the functionality of SyncRecMutex, like these locks
- * will not be cross process or passed to poll.
- *-----------------------------------------------------------------------------
- */
-#ifdef _WIN32
-
-typedef CRITICAL_SECTION VixLockType;
-static INLINE VixError VIX_INIT_LOCK(VixLockType *lockPtr);
-VixError VIX_INIT_LOCK(VixLockType *lockPtr)
-{
- InitializeCriticalSection(lockPtr);
- return VIX_OK;
-}
-#define VIX_DELETE_LOCK(lockPtr) DeleteCriticalSection(lockPtr)
-#define VIX_ENTER_LOCK(lockPtr) EnterCriticalSection(lockPtr)
-#define VIX_LEAVE_LOCK(lockPtr) LeaveCriticalSection(lockPtr)
-
-#else // #elif !_WIN32
-
-#ifdef __APPLE__
-#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
-#elif defined(__FreeBSD__) || defined(sun)
-#include <unistd.h>
-#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
-#else
-#include <linux/unistd.h>
-#endif
-
-#define _REENTRANT 1
-#include <pthread.h>
-#include <sys/types.h>
-
-typedef pthread_mutex_t VixLockType;
-static INLINE VixError VIX_INIT_LOCK(VixLockType *lockPtr);
-VixError VIX_INIT_LOCK(VixLockType *lockPtr)
-{
- int result;
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
-
- result = pthread_mutex_init(lockPtr, &attr);
- pthread_mutexattr_destroy(&attr);
- if (0 != result) {
- return VIX_E_OUT_OF_MEMORY;
- }
- return VIX_OK;
-}
-#define VIX_DELETE_LOCK(lockPtr) pthread_mutex_destroy(lockPtr)
-#define VIX_ENTER_LOCK(lockPtr) pthread_mutex_lock(lockPtr)
-#define VIX_LEAVE_LOCK(lockPtr) pthread_mutex_unlock(lockPtr)
-#define VIX_GET_THREADID() Util_GetCurrentThreadId()
-
-#endif // #ifdef LINUX
-
-
-
-/*
- * This represents one request we have received from the client
- * and are processing.
- */
-typedef struct ForeignVMToolsCommand {
- struct ForeignVMToolsConnection *connection;
- VixCommandRequestHeader requestHeader;
-
- char asyncOpName[32];
-
- int guestCredentialType;
- VixCommandNamePassword *guestUserNamePassword;
- char *obfuscatedGuestUserNamePassword;
- int obfuscatedCredentialType;
-
- VmTimeType programStartTime;
- int runProgramOptions;
-
- char *responseBody;
- size_t responseBodyLength;
-
- struct ForeignVMToolsCommand *next;
-} ForeignVMToolsCommand;
-
-
-/*
- * This represents one active connection to a Foundry client.
- */
-typedef struct ForeignVMToolsConnection {
- int socket;
-
- /*
- * This is the state of the message we are currently reading on
- * the connection. At any given time, we always have an outstanding
- * asynch read, which is waiting for the next request to arrive.
- */
- VixCommandRequestHeader requestHeader;
- char *completeRequest;
-
- struct ForeignVMToolsConnection *prev;
- struct ForeignVMToolsConnection *next;
-} ForeignVMToolsConnection;
-
-
-
-typedef enum FoundryDisconnectReason {
- SHUTDOWN_FOR_SYSTEM_SHUTDOWN,
- SHUTDOWN_FOR_PEER_DISCONNECT,
-} FoundryDisconnectReason;
-
-
-
-
-Bool ForeignTools_InitializeNetworking(void);
-
-void ForeignToolsSelectLoop(FoundryWorkerThread *threadState);
-
-void ForeignToolsCloseConnection(ForeignVMToolsConnection *connectionState,
- FoundryDisconnectReason reason);
-
-void ForeignToolsSendResponse(ForeignVMToolsConnection *connectionState,
- VixCommandRequestHeader *requestHeader,
- size_t responseBodyLength,
- void *responseBody,
- VixError error,
- uint32 additionalError,
- uint32 responseFlags);
-
-void ForeignToolsSendResponseUsingTotalMessage(ForeignVMToolsConnection *connectionState,
- VixCommandRequestHeader *requestHeader,
- size_t totalMessageSize,
- void *totalMessage,
- VixError error,
- uint32 additionalError,
- uint32 responseFlags);
-
-void ForeignToolsProcessMessage(ForeignVMToolsConnection *connectionState);
-
-void ForeignToolsDiscardCommand(ForeignVMToolsCommand *command);
-
-void ForeignToolsWakeSelectThread(void);
-
-
-extern VixLockType globalLock;
-
-extern struct ForeignVMToolsConnection *activeConnectionList;
-extern struct ForeignVMToolsCommand *globalCommandList;
-
-#endif /* __FOREIGN_VM_TOOLS_DAEMON_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdarg.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <MSWSock.h>
-#else
-#include <sys/types.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#include "vmware.h"
-#include "vm_version.h"
-#include "str.h"
-#include "hostinfo.h"
-#include "util.h"
-#include "dbllnklst.h"
-#include "eventManager.h"
-#include "SLPv2Private.h"
-#include "guestInfo.h"
-#include "netutil.h"
-#include "guestInfo.h"
-
-#include "vixOpenSource.h"
-#include "syncEvent.h"
-#include "foundryThreads.h"
-#include "vixCommands.h"
-#include "foreignVMToolsDaemon.h"
-
-
-#ifdef _WIN32
-#define ASOCK_ENOTCONN WSAENOTCONN
-#define ASOCK_ENOTSOCK WSAENOTSOCK
-#define ASOCK_ECONNECTING WSAEWOULDBLOCK
-#define ASOCK_EWOULDBLOCK WSAEWOULDBLOCK
-#else
-#define ASOCK_ENOTCONN ENOTCONN
-#define ASOCK_ENOTSOCK ENOTSOCK
-#define ASOCK_ECONNECTING EINPROGRESS
-#define ASOCK_EWOULDBLOCK EWOULDBLOCK
-#endif
-
-#define SLPV2_DEFAULT_SCOPE_NAME "DEFAULT"
-
-#if defined(__FreeBSD__) && !defined(_SOCKLEN_T_DECLARED)
-typedef int socklen_t;
-#endif
-
-
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Windows Procedure Pointers --
- *
- * We cannot link with winsock, since the DLL may not be present in all guests.
- * That would create a dll link problem that would prevent the tools from loading.
- * Instead, we try to get the procedure pointer ourselves at runtime, and quietly
- * fail if it is not there.
- *-----------------------------------------------------------------------------
- */
-#ifdef _WIN32
-typedef int (WSAAPI *WSAStartupProcType)(WORD wVersionRequested,
- LPWSADATA lpWSAData);
-
-typedef int (WSAAPI *WSAGetLastErrorProcType)(void);
-
-typedef u_long (WSAAPI *NtohlProcType)(u_long netlong);
-
-typedef u_long (WSAAPI *HtonlProcType)(u_long hostlong);
-
-typedef u_short (WSAAPI *HtonsProcType)(u_short hostshort);
-
-typedef int (WSAAPI *ClosesocketProcType)(SOCKET s);
-
-typedef SOCKET (WSAAPI *SocketProcType)(int af,
- int type,
- int protocol);
-
-typedef int (WSAAPI *ListenProcType)(SOCKET s,
- int backlog);
-
-typedef int (WSAAPI *BindProcType)(SOCKET s,
- const struct sockaddr FAR * name,
- int namelen);
-
-typedef SOCKET (WSAAPI *AcceptProcType)(SOCKET s,
- struct sockaddr FAR * addr,
- int FAR * addrlen);
-
-typedef int (WSAAPI *SendProcType)(SOCKET s,
- const char FAR * buf,
- int len,
- int flags);
-
-typedef int (WSAAPI *RecvProcType)(SOCKET s,
- char FAR * buf,
- int len,
- int flags);
-
-typedef int (WSAAPI *SelectProcType)(int nfds,
- fd_set* readfds,
- fd_set* writefds,
- fd_set* exceptfds,
- const struct timeval* timeout);
-
-typedef int (WSAAPI *IoctlsocketProcType)(SOCKET s,
- long cmd,
- u_long FAR * argp);
-
-typedef int (WSAAPI *SendToProcType)(SOCKET s,
- const char* buf,
- int len,
- int flags,
- const struct sockaddr* to,
- int tolen);
-
-typedef int (WSAAPI *SendSockOptProcType)(SOCKET s,
- int level,
- int optname,
- const void *optval,
- socklen_t optlen);
-
-typedef int (WSAAPI *WSAIoctlProcType)(SOCKET s,
- DWORD dwIoControlCode,
- LPVOID lpvInBuffer,
- DWORD cbInBuffer,
- LPVOID lpvOutBuffer,
- DWORD cbOutBuffer,
- LPDWORD lpcbBytesReturned,
- LPWSAOVERLAPPED lpOverlapped,
- LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
-
-typedef int (WSAAPI *WSAFDIsSetProcType)(SOCKET s,
- fd_set* set);
-
-typedef int (WSAAPI *RecvfromProcType)(SOCKET s,
- char* buf,
- int len,
- int flags,
- struct sockaddr* from,
- int* fromlen);
-
-
-static WSAStartupProcType VMToolsNet_WSAStartup = NULL;
-static WSAGetLastErrorProcType VMToolsNet_GetLastError = NULL;
-static NtohlProcType VMToolsNet_ntohl = NULL;
-static HtonlProcType VMToolsNet_htonl = NULL;
-static HtonsProcType VMToolsNet_htons = NULL;
-static ClosesocketProcType VMToolsNet_CloseSocket = NULL;
-static SocketProcType VMToolsNet_Socket = NULL;
-static ListenProcType VMToolsNet_Listen = NULL;
-static BindProcType VMToolsNet_Bind = NULL;
-static AcceptProcType VMToolsNet_Accept = NULL;
-static SendProcType VMToolsNet_Send = NULL;
-static RecvProcType VMToolsNet_Recv = NULL;
-static SelectProcType VMToolsNet_Select = NULL;
-static IoctlsocketProcType VMToolsNet_IoctlSocket = NULL;
-static SendToProcType VMToolsNet_Sendto = NULL;
-static SendSockOptProcType VMToolsNet_SetSockOpt = NULL;
-static WSAIoctlProcType VMToolsNet_WSAIoctl = NULL;
-static WSAFDIsSetProcType VMToolsNet_FDIsSet = NULL;
-static RecvfromProcType VMToolsNet_Recvfrom = NULL;
-
-
-// ifdef _WIN32
-#else
-#define VMToolsNet_GetLastError() errno
-#define VMToolsNet_ntohl ntohl
-#define VMToolsNet_htonl htonl
-#define VMToolsNet_htons htons
-#define VMToolsNet_Socket socket
-#define VMToolsNet_Listen listen
-#define VMToolsNet_Bind bind
-#define VMToolsNet_Accept accept
-#define VMToolsNet_Send send
-#define VMToolsNet_Recv recv
-#define VMToolsNet_Select select
-#define VMToolsNet_CloseSocket close
-#define VMToolsNet_IoctlSocket ioctl
-#define VMToolsNet_Sendto sendto
-#define VMToolsNet_SetSockOpt setsockopt
-#define VMToolsNet_SetSockOpt setsockopt
-#define VMToolsNet_FDIsSet FD_ISSET
-#define VMToolsNet_Recvfrom recvfrom
-
-#endif
-
-
-Bool ForeignToolsMakeNonBlocking(int fd);
-
-static Bool ForeignToolsSocketBind(int fd,
- unsigned int ip,
- unsigned short port);
-
-static Bool ForeignToolsAcceptConnection(int tcpListenerSocket);
-
-static void ForeignToolsProcessUDP(int tcpListenerSocket);
-
-static void ForeignToolsReadRequest(ForeignVMToolsConnection *connectionState);
-
-static int VixSocketListenerPort = VIX_TOOLS_SOCKET_PORT;
-static int SLPv2SocketListenerPort = SLPV2_HIGHPORT; // SLPV2_PORT;
-
-static char globalHostName[512];
-
-static char globalSLPv2ServiceProperties[1024];
-
-static int udpListenerSocket = -1;
-
-#define VIX_SLPV2_PROPERTY_PORT "port"
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignTools_InitializeNetworking --
- *
- * Start a worker thread.
- *
- * Results:
- * FoundryWorkerThread *
- *
- * Side effects:
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-ForeignTools_InitializeNetworking(void)
-{
- Bool success = TRUE;
- const char *globalHostInfoStr;
- char *ipAddressStr = NULL;
- char *destPtr;
- char *endDestPtr;
- GuestNicList nicInfo;
-#ifdef _WIN32
- HMODULE hWs2_32 = NULL;
- WSADATA wsaData;
- WORD versionRequested = MAKEWORD(2, 0);
-#endif
-
-
- globalHostInfoStr = Hostinfo_NameGet();
- if (NULL == globalHostInfoStr) {
- globalHostName[0] = 0;
- } else {
- Str_Strcpy(globalHostName, globalHostInfoStr, sizeof(globalHostName));
- }
-
-#ifdef _WIN32
- hWs2_32 = LoadLibrary(_T("ws2_32.dll"));
- if (NULL == hWs2_32) {
- goto abort;
- }
-
- VMToolsNet_WSAStartup = (WSAStartupProcType) GetProcAddress(hWs2_32, "WSAStartup");
- if (NULL == VMToolsNet_WSAStartup) {
- goto abort;
- }
-
- VMToolsNet_GetLastError = (WSAGetLastErrorProcType) GetProcAddress(hWs2_32, "WSAGetLastError");
- if (NULL == VMToolsNet_GetLastError) {
- goto abort;
- }
-
- VMToolsNet_ntohl = (NtohlProcType) GetProcAddress(hWs2_32, "ntohl");
- if (NULL == VMToolsNet_ntohl) {
- goto abort;
- }
-
- VMToolsNet_htonl = (HtonlProcType) GetProcAddress(hWs2_32, "htonl");
- if (NULL == VMToolsNet_htonl) {
- goto abort;
- }
-
- VMToolsNet_htons = (HtonsProcType) GetProcAddress(hWs2_32, "htons");
- if (NULL == VMToolsNet_htons) {
- goto abort;
- }
-
- VMToolsNet_CloseSocket = (ClosesocketProcType) GetProcAddress(hWs2_32, "closesocket");
- if (NULL == VMToolsNet_CloseSocket) {
- goto abort;
- }
-
- VMToolsNet_Socket = (SocketProcType) GetProcAddress(hWs2_32, "socket");
- if (NULL == VMToolsNet_Socket) {
- goto abort;
- }
-
- VMToolsNet_Listen = (ListenProcType) GetProcAddress(hWs2_32, "listen");
- if (NULL == VMToolsNet_Listen) {
- goto abort;
- }
-
- VMToolsNet_Bind = (BindProcType) GetProcAddress(hWs2_32, "bind");
- if (NULL == VMToolsNet_Bind) {
- goto abort;
- }
-
- VMToolsNet_Accept = (AcceptProcType) GetProcAddress(hWs2_32, "accept");
- if (NULL == VMToolsNet_Accept) {
- goto abort;
- }
-
- VMToolsNet_Send = (SendProcType) GetProcAddress(hWs2_32, "send");
- if (NULL == VMToolsNet_Send) {
- goto abort;
- }
-
- VMToolsNet_Recv = (RecvProcType) GetProcAddress(hWs2_32, "recv");
- if (NULL == VMToolsNet_Recv) {
- goto abort;
- }
-
- VMToolsNet_Select = (SelectProcType) GetProcAddress(hWs2_32, "select");
- if (NULL == VMToolsNet_Select) {
- goto abort;
- }
-
- VMToolsNet_IoctlSocket = (IoctlsocketProcType) GetProcAddress(hWs2_32, "ioctlsocket");
- if (NULL == VMToolsNet_IoctlSocket) {
- return FALSE;
- }
-
- VMToolsNet_Sendto = (SendToProcType) GetProcAddress(hWs2_32, "sendto");
- if (NULL == VMToolsNet_Sendto) {
- return FALSE;
- }
-
- VMToolsNet_SetSockOpt = (SendSockOptProcType) GetProcAddress(hWs2_32, "setsockopt");
- if (NULL == VMToolsNet_SetSockOpt) {
- return FALSE;
- }
-
- VMToolsNet_WSAIoctl = (WSAIoctlProcType) GetProcAddress(hWs2_32, "WSAIoctl");
- if (NULL == VMToolsNet_WSAIoctl) {
- return FALSE;
- }
-
- VMToolsNet_FDIsSet = (WSAFDIsSetProcType) GetProcAddress(hWs2_32, "__WSAFDIsSet");
- if (NULL == VMToolsNet_FDIsSet) {
- return FALSE;
- }
-
- VMToolsNet_Recvfrom = (RecvfromProcType) GetProcAddress(hWs2_32, "recvfrom");
- if (NULL == VMToolsNet_Recvfrom) {
- return FALSE;
- }
-
-
- if (0 != VMToolsNet_WSAStartup(versionRequested, &wsaData)) {
- goto abort;
- }
-
- NetUtil_LoadIpHlpApiDll();
-#endif // _WIN32
-
- /*
- * Build up a description of this host/guest that we can broadcast
- * over SLPv2.
- */
- destPtr = globalSLPv2ServiceProperties;
- endDestPtr = globalSLPv2ServiceProperties + sizeof(globalSLPv2ServiceProperties);
-
- ipAddressStr = NetUtil_GetPrimaryIP();
- if (NULL == ipAddressStr) {
- ipAddressStr = Util_SafeStrdup("");
- }
- destPtr += Str_Snprintf(destPtr,
- endDestPtr - destPtr,
- "%s=%s;",
- VIX_SLPV2_PROPERTY_IP_ADDR,
- ipAddressStr);
- destPtr += Str_Snprintf(destPtr,
- endDestPtr - destPtr,
- "%s=%d;",
- VIX_SLPV2_PROPERTY_PORT,
- VixSocketListenerPort);
-
- /*
- * Find out how big the IP_ADAPTER_INFO table needs to be.
- */
- success = GuestInfo_GetNicInfo(&nicInfo);
- if (success) {
- u_int i;
- for (i = 0; i < nicInfo.nics.nics_len; i++) {
- GuestNic *nic = &nicInfo.nics.nics_val[i];
- destPtr += Str_Snprintf(destPtr,
- endDestPtr - destPtr,
- "%s=%s;",
- VIX_SLPV2_PROPERTY_MAC_ADDR,
- nic->macAddress);
- }
- VMX_XDR_FREE(xdr_GuestNicList, &nicInfo);
- }
-
- free(ipAddressStr);
- return(TRUE);
-
-#ifdef _WIN32
-abort:
- return(FALSE);
-#endif
-} // ForeignTools_InitializeNetworking
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsMakeNonBlocking --
- *
- * Make the specified socket non-blocking if it isn't already.
- *
- * Results:
- * TRUE if the operation succeeded, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-ForeignToolsMakeNonBlocking(int fd) // IN
-{
-#ifdef _WIN32
- int retval;
- u_long argp = 1; /* non-zero => enable non-blocking mode */
-
- retval = VMToolsNet_IoctlSocket(fd, FIONBIO, &argp);
- if (retval != 0) {
- return FALSE;
- }
-
-#else
- int flags;
-
- if ((flags = fcntl(fd, F_GETFL)) < 0) {
- return FALSE;
- }
-
- if (!(flags & O_NONBLOCK) && (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)) {
- return FALSE;
- }
-#endif
- return TRUE;
-} // ForeignToolsMakeNonBlocking
-
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsSocketBind --
- *
- * This is an internal routine that binds a socket to a port.
- *
- * Results:
- * Returns TRUE upon success, FALSE upon failure.
- *
- * Side effects:
- * Socket is bound to a particular port.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-ForeignToolsSocketBind(int fd, // IN
- unsigned int ip, // IN
- unsigned short port) // IN
-{
- struct sockaddr_in local_addr = { 0 };
- int error = 0;
- int reuse = port != 0;
-
-#ifndef _WIN32
- /*
- * Don't ever use SO_REUSEADDR on Windows; it doesn't mean what you think
- * it means.
- */
- if (VMToolsNet_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR,
- (const void *) &reuse, sizeof(reuse)) != 0) {
- error = VMToolsNet_GetLastError();
- }
-#endif
-
-#ifdef _WIN32
- /*
- * Always set SO_EXCLUSIVEADDRUSE on Windows, to prevent other applications
- * from stealing this socket. (Yes, Windows is that stupid).
- */
- {
- int exclusive = 1;
- if (VMToolsNet_SetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
- (const void *) &exclusive, sizeof(exclusive)) != 0) {
- error = VMToolsNet_GetLastError();
- }
- }
-#endif
-
- /*
- * Bind to a port
- */
- local_addr.sin_family = AF_INET;
- local_addr.sin_addr.s_addr = VMToolsNet_htonl(ip);
- local_addr.sin_port = VMToolsNet_htons(port);
-
- if (VMToolsNet_Bind(fd, (struct sockaddr *) &local_addr, sizeof(local_addr)) != 0) {
- error = VMToolsNet_GetLastError();
- goto error;
- }
-
- return TRUE;
-
-error:
- return FALSE;
-} // ForeignToolsSocketBind
-
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsSelectLoop --
- *
- * This is the main loop for the select thread.
- *
- * Results:
- * None
- *
- * Side effects:
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsSelectLoop(FoundryWorkerThread *threadState) // IN
-{
- Bool success;
- int retval;
-#ifdef _WIN32
- struct fd_set rwfds;
- struct fd_set exceptfds;
-#else
- fd_set rwfds;
- fd_set exceptfds;
-#endif
- ForeignVMToolsConnection *connectionState = NULL;
- int numFDs;
- int bcast = 1;
- int tcpListenerSocket = -1;
-
-
- if (NULL == threadState) {
- ASSERT(0);
- return;
- }
-
- /*
- * Create the socket we will listen on.
- */
- tcpListenerSocket = VMToolsNet_Socket(AF_INET, SOCK_STREAM, 0);
- if (tcpListenerSocket == -1) {
- goto abort;
- }
- //success = ForeignToolsMakeNonBlocking(tcpListenerSocket);
- success = ForeignToolsSocketBind(tcpListenerSocket,
- INADDR_ANY,
- VixSocketListenerPort);
- if (!success) {
- goto abort;
- }
- if (VMToolsNet_Listen(tcpListenerSocket, 5) != 0) {
- goto abort;
- }
- udpListenerSocket = VMToolsNet_Socket(AF_INET, SOCK_DGRAM, 0);
- if (udpListenerSocket == -1) {
- goto abort;
- }
- //success = ForeignToolsMakeNonBlocking(tcpListenerSocket);
- success = ForeignToolsSocketBind(udpListenerSocket,
- INADDR_ANY,
- SLPv2SocketListenerPort);
- if (!success) {
- goto abort;
- }
- VMToolsNet_SetSockOpt(udpListenerSocket,
- SOL_SOCKET,
- SO_BROADCAST,
- (const void *) &bcast,
- sizeof(bcast));
-
-#ifdef _WIN32
- {
- /*
- * On Windows, sending a UDP packet to a host may result in
- * a "connection reset by peer" message to be sent back by
- * the remote machine. If that happens, our UDP socket becomes
- * useless. We can disable this with the SIO_UDP_CONNRESET
- * ioctl option.
- */
- DWORD dwBytesReturned = 0;
- BOOL bNewBehavior = FALSE;
- DWORD status;
- status = VMToolsNet_WSAIoctl(udpListenerSocket,
- SIO_UDP_CONNRESET,
- &bNewBehavior,
- sizeof(bNewBehavior),
- NULL,
- 0,
- &dwBytesReturned,
- NULL,
- NULL);
- if (SOCKET_ERROR == status) {
- }
- }
-#endif
-
-
- /*
- * This is the main select thread loop.
- */
- while (!(threadState->stopThread)) {
- /*
- * Listen for activity on any socket we care about.
- */
- FD_ZERO(&rwfds);
- FD_ZERO(&exceptfds);
- FD_SET(tcpListenerSocket, &rwfds);
- FD_SET(tcpListenerSocket, &exceptfds);
- FD_SET(udpListenerSocket, &rwfds);
- FD_SET(udpListenerSocket, &exceptfds);
- numFDs = 2;
-
- VIX_ENTER_LOCK(&globalLock);
- connectionState = activeConnectionList;
- while (NULL != connectionState) {
- FD_SET(connectionState->socket, &rwfds);
- FD_SET(connectionState->socket, &exceptfds);
- numFDs += 1;
- connectionState = connectionState->next;
- }
- VIX_LEAVE_LOCK(&globalLock);
-
- retval = VMToolsNet_Select(numFDs, &rwfds, NULL, &exceptfds, NULL);
-
- if (threadState->stopThread) {
- break;
- }
-
- /*
- * No sockets were ready or else we were interrupted by signal.
- * Loop and retry.
- */
- if (retval <= 0) {
- continue;
- }
-
- if (VMToolsNet_FDIsSet(tcpListenerSocket, &rwfds)) {
- success = ForeignToolsAcceptConnection(tcpListenerSocket);
- if (!success) {
- break;
- }
- }
-
- if (VMToolsNet_FDIsSet(udpListenerSocket, &rwfds)) {
- ForeignToolsProcessUDP(udpListenerSocket);
- }
-
- VIX_ENTER_LOCK(&globalLock);
- connectionState = activeConnectionList;
- while (NULL != connectionState) {
- ForeignVMToolsConnection *nextConnection;
-
- /*
- * Save the next connection in case we close this connection.
- */
- nextConnection = connectionState->next;
-
- if (VMToolsNet_FDIsSet(connectionState->socket, &rwfds)) {
- ForeignToolsReadRequest(connectionState);
- } else if (VMToolsNet_FDIsSet(connectionState->socket, &exceptfds)) {
- ForeignToolsCloseConnection(connectionState, SHUTDOWN_FOR_PEER_DISCONNECT);
- }
-
- connectionState = nextConnection;
- }
- VIX_LEAVE_LOCK(&globalLock);
- } // while (!(threadState->stopThread))
-
-abort:
- if (tcpListenerSocket != -1) {
- VMToolsNet_CloseSocket(tcpListenerSocket);
- }
- if (udpListenerSocket != -1) {
- VMToolsNet_CloseSocket(udpListenerSocket);
- udpListenerSocket = -1;
- }
-} // ForeignToolsSelectLoop
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsAcceptConnection --
- *
- *
- * Results:
- * None
- *
- * Side effects:
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-ForeignToolsAcceptConnection(int tcpListenerSocket) // IN
-{
- int retval;
- struct sockaddr remoteAddr;
- socklen_t remoteAddrLen = sizeof remoteAddr;
- ForeignVMToolsConnection *connectionState = NULL;
-
-
- retval = VMToolsNet_Accept(tcpListenerSocket, &remoteAddr, &remoteAddrLen);
- if (retval == -1) {
- retval = VMToolsNet_GetLastError();
- if (retval == ASOCK_EWOULDBLOCK) {
- return TRUE; // Ignore this error, so return success
-#ifndef _WIN32
- } else if (retval == ECONNABORTED) {
- return TRUE; // Ignore this error, so return success
-#endif
- } else {
- return FALSE; // OK, now this is an error.
- }
- }
-
-
- VIX_ENTER_LOCK(&globalLock);
-
- /*
- * Allocate some state for the connection
- */
- connectionState = Util_SafeCalloc(1, sizeof *connectionState);
- connectionState->socket = retval;
-
- connectionState->prev = NULL;
- connectionState->next = activeConnectionList;
- if (NULL != activeConnectionList) {
- activeConnectionList->prev = connectionState;
- }
- activeConnectionList = connectionState;
-
- VIX_LEAVE_LOCK(&globalLock);
-
- return(TRUE);
-} // ForeignToolsAcceptConnection
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsReadRequest --
- *
- *
- * Results:
- * None
- *
- * Side effects:
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsReadRequest(ForeignVMToolsConnection *connectionState) // IN
-{
- VixError err = VIX_OK;
- int result;
-
- /*
- * Read the message header.
- */
- result = VMToolsNet_Recv(connectionState->socket,
- (char *) &(connectionState->requestHeader),
- sizeof(connectionState->requestHeader),
- 0);
- if (result <= 0) {
- ForeignToolsCloseConnection(connectionState, SHUTDOWN_FOR_PEER_DISCONNECT);
- goto abort;
- }
-
- /*
- * Sanity check the request header.
- */
- err = VixMsg_ValidateRequestMsg(&(connectionState->requestHeader), result);
- if (VIX_OK != err) {
- goto abort;
- }
-
- connectionState->completeRequest
- = Util_SafeMalloc(connectionState->requestHeader.commonHeader.totalMessageLength);
- memcpy(connectionState->completeRequest,
- &(connectionState->requestHeader),
- result);
-
- /*
- * If this request has a variable-sized part, like a body or a user credential,
- * then start reading that. Otherwise, if the request only has a fixed-size header,
- * then we can start processing it now.
- */
- if (connectionState->requestHeader.commonHeader.totalMessageLength > result) {
- result = VMToolsNet_Recv(connectionState->socket,
- connectionState->completeRequest + result,
- connectionState->requestHeader.commonHeader.totalMessageLength - result,
- 0);
- if (result <= 0) {
- ForeignToolsCloseConnection(connectionState, SHUTDOWN_FOR_PEER_DISCONNECT);
- goto abort;
- }
- }
-
- ForeignToolsProcessMessage(connectionState);
-
-abort:
- if (VIX_OK != err) {
- ForeignToolsSendResponse(connectionState,
- &(connectionState->requestHeader),
- 0, // responseBodyLength
- NULL, // responseBody
- err,
- 0, // additionalError
- 0); // responseFlags;
- }
-} // ForeignToolsReadRequest
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsSendResponse --
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsSendResponse(ForeignVMToolsConnection *connectionState, // IN
- VixCommandRequestHeader *requestHeader, // IN
- size_t responseBodyLength, // IN
- void *responseBody, // IN
- VixError error, // IN
- uint32 additionalError, // IN
- uint32 responseFlags) // IN
-{
- int result = 0;
- VixCommandResponseHeader *responseHeader = NULL;
- size_t totalMessageSize;
-
- responseHeader = VixMsg_AllocResponseMsg(requestHeader,
- error,
- additionalError,
- responseBodyLength,
- responseBody,
- &totalMessageSize);
-
- responseHeader->responseFlags |= responseFlags;
-
- result = VMToolsNet_Send(connectionState->socket,
- (const char *) responseHeader,
- totalMessageSize,
- 0);
- if (result <= 0) {
- }
-
- free(responseHeader);
-} // ForeignToolsSendResponse
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsSendResponseUsingTotalMessage --
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsSendResponseUsingTotalMessage(ForeignVMToolsConnection *connectionState, // IN
- VixCommandRequestHeader *requestHeader, // IN
- size_t totalMessageSize, // IN
- void *totalMessage, // IN
- VixError error, // IN
- uint32 additionalError, // IN
- uint32 responseFlags) // IN
-{
- int result = 0;
- VixCommandResponseHeader *responseHeader;
-
- if ((totalMessageSize <= 0) || (NULL == totalMessage)) {
- return;
- }
-
- responseHeader = (VixCommandResponseHeader *) totalMessage;
- VixMsg_InitResponseMsg(responseHeader,
- requestHeader,
- error,
- additionalError,
- totalMessageSize);
-
- responseHeader->responseFlags |= responseFlags;
-
- result = VMToolsNet_Send(connectionState->socket,
- (const char *) responseHeader,
- totalMessageSize,
- 0);
- if (result <= 0) {
- }
-} // ForeignToolsSendResponseUsingTotalMessage
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ForeignToolsProcessUDP --
- *
- *
- * Results:
- * None
- *
- * Side effects:
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsProcessUDP(int udpListenerSocket) // IN
-{
- struct sockaddr_in clientAddr;
- int clientAddrLen = sizeof(clientAddr);
- int actualPacketLength = 0;
- char receiveBuffer[2048];
- struct SLPv2_Parse *parser = NULL;
- Bool success;
- uint16 xid;
- Bool match;
- char urlBuffer[1024];
- char *urlList[] = { urlBuffer };
- char *replyPacket = NULL;
- int replyPacketSize = 0;
-
- actualPacketLength = VMToolsNet_Recvfrom(udpListenerSocket,
- receiveBuffer,
- sizeof(receiveBuffer),
- 0,
- (struct sockaddr *) &clientAddr,
- &clientAddrLen);
- if (actualPacketLength <= 0) {
- goto abort;
- }
-
-
- parser = SLPv2MsgParser_Init();
- success = SLPv2MsgParser_Parse(parser, receiveBuffer, actualPacketLength);
- if (!success) {
- goto abort;
- }
-
- /*
- * First, check if this is a general request to find all hosts
- * runn a particular type of service.
- */
- match = SLPv2MsgParser_ServiceRequestMatch(parser,
- "", // previous responder list
- VIX_SLPV2_SERVICE_NAME_TOOLS_SERVICE, // service
- SLPV2_DEFAULT_SCOPE_NAME, // scope
- "", // LDAPv3 predicate
- &xid);
- if (match) {
- Str_Sprintf(urlBuffer,
- sizeof urlBuffer,
- "%s://%s/",
- VIX_SLPV2_SERVICE_NAME_TOOLS_SERVICE,
- globalHostName);
- success = SLPv2MsgAssembler_ServiceReply(&replyPacket,
- &replyPacketSize,
- xid, // xid from service request msg
- "en", // language
- 0, // error code
- 1, // URL count
- urlList);
- /*
- * Otherwise, check if this is a specific request to find all attributes
- * of this specific service instance.
- */
- } else {
- match = SLPv2MsgParser_AttributeRequestMatch(parser,
- NULL,
- NULL,
- NULL,
- NULL,
- &xid);
- if (match) {
- success = SLPv2MsgAssembler_AttributeReply(&replyPacket,
- &replyPacketSize,
- xid, // xid from request
- "en", // language
- 0, // error code
- globalSLPv2ServiceProperties); // attributes
- } // if (match)
- }
-
- /*
- * If we have a response to the request, then send it and stop looking
- * for more responses.
- */
- if (NULL != replyPacket) {
- VMToolsNet_Sendto(udpListenerSocket,
- replyPacket,
- replyPacketSize,
- 0, // flags
- (struct sockaddr *) &clientAddr,
- clientAddrLen);
- }
-
-abort:
- free(replyPacket);
- SLPv2MsgParser_Destroy(parser);
-} // ForeignToolsProcessUDP
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsCloseConnection --
- *
- * Closes the socket.
- *
- * Results:
- * None.
- *
- * Side effects:
- *
- *----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsCloseConnection(ForeignVMToolsConnection *connectionState, // IN
- FoundryDisconnectReason reason) // IN
-{
- ForeignVMToolsConnection *targetConnection = NULL;
- Bool holdingLock = FALSE;
- ForeignVMToolsCommand *command;
- ForeignVMToolsCommand *nextCommand;
-
-
- if (NULL == connectionState) {
- return;
- }
-
- VIX_ENTER_LOCK(&globalLock);
- holdingLock = TRUE;
-
- /*
- * It's possible that data on a connection arrives late, after we have
- * closed it. In that case, VMAutomationReceiveMessage will correctly
- * not process the data. But, be careful that we don't try to close
- * the connection again.
- */
- targetConnection = activeConnectionList;
- while (NULL != targetConnection) {
- if (targetConnection == connectionState) {
- break;
- }
- targetConnection = targetConnection->next;
- }
- if (NULL == targetConnection) {
- goto abort;
- }
-
- /*
- * Discard any commands we received on this connection.
- */
- command = globalCommandList;
- while (NULL != command) {
- nextCommand = command->next;
- if (connectionState == command->connection) {
- if (SHUTDOWN_FOR_PEER_DISCONNECT != reason) {
- ForeignToolsSendResponse(connectionState,
- &(connectionState->requestHeader),
- 0, // responseBodyLength
- NULL, // responseBody
- VIX_OK, // err,
- 0, // additionalError
- 0); // responseFlags
- }
-
- ForeignToolsDiscardCommand(command);
- }
-
- command = nextCommand;
- } // while (NULL != command)
-
- /*
- * Remove the connection from the global list.
- */
- if (NULL != connectionState->prev) {
- connectionState->prev->next = connectionState->next;
- } else {
- activeConnectionList = connectionState->next;
- }
- if (NULL != connectionState->next) {
- connectionState->next->prev = connectionState->prev;
- }
-
- VIX_LEAVE_LOCK(&globalLock);
- holdingLock = FALSE;
-
- if (connectionState->socket >= 0) {
- VMToolsNet_CloseSocket(connectionState->socket);
- }
-
- //if (NULL != connectionState->sessionKey) {
- // CryptoKey_Free(connectionState->sessionKey);
- //}
-
- free(connectionState);
-
-abort:
- if (holdingLock) {
- VIX_LEAVE_LOCK(&globalLock);
- }
-} // ForeignToolsCloseConnection
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ForeignToolsWakeSelectThread --
- *
- * Closes the socket.
- *
- * Results:
- * None.
- *
- * Side effects:
- *
- *----------------------------------------------------------------------------
- */
-
-void
-ForeignToolsWakeSelectThread(void) // IN
-{
- struct sockaddr_in localAddr = { 0 };
- char packet[2];
-
- if (-1 == udpListenerSocket) {
- return;
- }
-
- localAddr.sin_family = AF_INET;
- localAddr.sin_addr.s_addr = VMToolsNet_htonl(INADDR_ANY);
- localAddr.sin_port = VMToolsNet_htons(SLPv2SocketListenerPort);
-
- VMToolsNet_Sendto(udpListenerSocket,
- packet,
- sizeof(packet),
- 0, // flags
- (struct sockaddr *) &localAddr,
- sizeof(localAddr));
-} // ForeignToolsWakeSelectThread
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * guestd_version.h --
- *
- * Version definitions for guestd.
- */
-
-#ifndef _GUESTD_VERSION_H_
-#define _GUESTD_VERSION_H_
-
-/*
- * This component's version is coupled with Tools versioning. The effect
- * is that the version increments with each build, and with each Tools
- * version bump. If and when it becomes necessary to version the component
- * manually, make sure that the version is bumped any time the component or
- * its dependencies are changed.
- */
-#include "vm_tools_version.h"
-#define GUESTD_VERSION_COMMAS TOOLS_VERSION_EXT_CURRENT_CSV
-#define GUESTD_VERSION_STRING TOOLS_VERSION_EXT_CURRENT_STR
-
-#endif /* _GUESTD_VERSION_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-
-/*
- * main.c --
- *
- * Guest application started as a service
- * Linux and FreeBSD implementation
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <stdlib.h>
-
-
-#include "vmware.h"
-#include "toolsDaemon.h"
-#include "eventManager.h"
-#include "rpcout.h"
-#include "rpcin.h"
-#include "vm_app.h"
-#include "debug.h"
-#include "vmsignal.h"
-#include "guestApp.h"
-#include "vmcheck.h"
-#include "util.h"
-#include "strutil.h"
-#include "str.h"
-#include "vm_version.h"
-#include "procMgr.h"
-#include "system.h"
-#include "conf.h"
-#include "guestInfo.h"
-#include "guestInfoServer.h"
-#include "escape.h"
-#include "vmstdio.h"
-#include "vmBackup.h"
-#include "codeset.h"
-
-#if !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
-#include "socketMgr.h"
-#endif
-
-/* Header to get prototype of daemon() implementation for Solaris. */
-#ifdef sun
-# include "miscSolaris.h"
-#endif
-
-#include "procMgr.h"
-#include "guestd_version.h"
-
-#include "embed_version.h"
-/*
- * XXX VM_EMBED_VERSION is ELF-specific, and Mac OS doesn't grok that.
- */
-#ifndef __APPLE__
-VM_EMBED_VERSION(GUESTD_VERSION_STRING);
-#endif
-
-/*
- * Global constants
- */
-
-#define DEFAULT_PIDFILE "/var/run/vmware-guestd.pid"
-#define EXEC_LOG "/var/log/vmware-tools-guestd"
-#define UPGRADER_FILENAME "vmware-tools-upgrader"
-
-
-/*
- * All signals that:
- * . Can terminate the process
- * . May occur even if the program has no bugs
- */
-static int const cSignals[] = {
- SIGHUP,
- SIGINT,
- SIGQUIT,
- SIGTERM,
- SIGUSR1,
- SIGUSR2,
-};
-
-
-/*
- * Global variables
- */
-
-
-/*
- * What a pity that the signal API doesn't allow to pass a clientData
- * parameter :( --hpreg
- */
-static int gDaemonSignal;
-static int gCommandLineRpciSignal;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdCommandLineRpciSignal --
- *
- * Command line RPCI signal handler
- *
- * Return value:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-GuestdCommandLineRpciSignal(int signal)
-{
- Debug("Received signal %d\n", signal);
-
- /*
- * Sending a command line RPCI doesn't take a long time. Delay the handling
- * of the signal until we have closed the RpcOut object --hpreg
- */
-
- if (gCommandLineRpciSignal == 0) {
- /*
- * This is the first signal we receive
- */
-
- ASSERT(signal);
- gCommandLineRpciSignal = signal;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdCommandLineRpci --
- *
- * Make VMware execute a RPCI string command, and output the string result
- * on stdout
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GuestdCommandLineRpci(char const *cmd) // IN: RPCI command
-{
- struct sigaction olds[ARRAYSIZE(cSignals)];
- char *result = NULL;
- Bool status = FALSE;
- Bool signaled = FALSE;
-
- gCommandLineRpciSignal = 0;
-
- if (Signal_SetGroupHandler(cSignals, olds, ARRAYSIZE(cSignals),
- GuestdCommandLineRpciSignal) == 0) {
- return FALSE;
- }
-
- status = RpcOut_sendOne(&result, NULL, "%s", cmd);
-
- if (gCommandLineRpciSignal) {
- fprintf(stderr, "Interrupted by signal %d.\n\n", gCommandLineRpciSignal);
- signaled = TRUE;
- }
-
- if ((Signal_ResetGroupHandler(cSignals, olds, ARRAYSIZE(cSignals)) == 0) ||
- signaled) {
- status = FALSE;
- } else if (!status) {
- fprintf(stderr, "%s\n", result ? result : "NULL");
- } else {
- printf("%s\n", result);
- }
-
- free(result);
- return status;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdDaemonSignal --
- *
- * Daemon signal handler
- *
- * Return value:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-GuestdDaemonSignal(int signal)
-{
- Debug("Received signal %d\n", signal);
-
- /*
- * This code can be executed at any time, and can preempt the "normal" flow
- * of execution.
- *
- * To avoid re-entrancy and concurrency issues in the "normal" code, we
- * defer the handling of the signal until we are in a well-known context
- *
- * --hpreg
- */
-
- if (gDaemonSignal == 0) {
- /*
- * This is the first signal we receive
- */
-
- ASSERT(signal);
- gDaemonSignal = signal;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdExecute --
- *
- * Callback-able wrappers to execute halt/reboot commands.
- *
- * Results:
- * TRUE on success
- * FALSE on failure
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GuestdExecute(void *clientData, const char *confName)
-{
- GuestApp_Dict **pConfDict = (GuestApp_Dict **) clientData;
- const char *cmd;
-
- ASSERT(confName);
- ASSERT(pConfDict);
- ASSERT(*pConfDict);
-
- cmd = GuestApp_GetDictEntry(*pConfDict, confName);
- ASSERT(cmd);
-
- return ProcMgr_ExecSync(cmd, NULL);
-}
-
-static Bool
-GuestdExecuteHalt(void *clientData)
-{
- return GuestdExecute(clientData, CONFNAME_HALT);
-}
-
-static Bool
-GuestdExecuteReboot(void *clientData)
-{
- return GuestdExecute(clientData, CONFNAME_REBOOT);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdCreateUpgrader --
- *
- * Spawn a new process that manages the auto-upgrade procedure.
- *
- * Results:
- * Return value specifies result of fork/exec.
- *
- * Side effects:
- * Spawns a new process.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GuestdCreateUpgrader(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // Ignored
- const char *args, // Ignored
- size_t argsSize, // Ignored
- void *clientData) // Ignored
-{
- int32 version;
- unsigned int index = 0;
- const char *upgraderPath = NULL;
- char *upgraderCmd = NULL;
- ProcMgr_AsyncProc *upgraderProc = NULL;
-
- if (StrUtil_GetNextIntToken(&version, &index, args, " ")) {
- /* New protocol. Host sent 'upgrader.create <version>' */
- if (version == 1) {
- upgraderPath = ToolsDaemon_GetGuestTempDirectory();
- if (upgraderPath == NULL) {
- Log("ToolsDaemon_GetGuestTempDirectory failed.\n");
- return RpcIn_SetRetVals(result, resultLen,
- "ToolsDaemon_GetGuestTempDirectory failed", FALSE);
- }
-
- upgraderCmd = Str_Asprintf(NULL, "bash %s%srun_upgrader.sh",
- upgraderPath, DIRSEPS);
- if (upgraderCmd == NULL) {
- Log("Str_Asprintf failed.\n");
- return RpcIn_SetRetVals(result, resultLen,
- "Str_Asprintf failed", FALSE);
- }
- } else {
- return RpcIn_SetRetVals(result, resultLen, "Unknown protocol version", FALSE);
- }
- } else {
- /* Old protocol. Host sent 'upgrader.create' */
- upgraderCmd = Util_SafeStrdup(UPGRADER_FILENAME);
- }
-
- upgraderProc = ProcMgr_ExecAsync(upgraderCmd, NULL);
- free(upgraderCmd);
- if (upgraderProc == NULL) {
- Warning("Failed to start upgrader.\n");
- return RpcIn_SetRetVals(result, resultLen, "ProcMgr_ExecAsync failed", FALSE);
- }
- ProcMgr_Free(upgraderProc);
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdSleep --
- *
- * Sleep in a non-blocking way for the given number of
- * micro-seconds. The callback is called if the async proc
- * exits.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-GuestdSleep(uint64 numUsecs, // IN
- const ToolsDaemon_Data *tdData) // IN
-{
- static ProcMgr_AsyncProc *curAsyncProc = NULL;
- static int asyncFd; /*
- * Fd for asyncProc. Only meaningful
- * if (curAsyncProc != NULL).
- */
- int maxFd; /* Max fd of all Fd sets */
- fd_set readFds; /* Read fd set to select on */
- fd_set writeFds;
-#if !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
- SocketSelectable *sockReadFds = NULL;
- SocketSelectable *sockWriteFds = NULL;
- int numSockReadFds = 0;
- int numSockWriteFds = 0;
- int index;
-#endif
- struct timeval tv;
- int status;
-
- ASSERT(tdData);
-
- /* If there is a new async proc, init the fd set & fd max */
- if (tdData->asyncProc && !curAsyncProc) {
- asyncFd = ProcMgr_GetAsyncProcSelectable(tdData->asyncProc);
- curAsyncProc = tdData->asyncProc;
- } else {
- /*
- * Make sure the caller doesn't try to change the asyncProc before
- * its fd has been selected.
- */
- ASSERT(tdData->asyncProc == curAsyncProc);
- }
-
- /* Init readFds & writeFds */
- FD_ZERO(&readFds);
- FD_ZERO(&writeFds);
- maxFd = -1;
-
- if (curAsyncProc) {
- FD_SET(asyncFd, &readFds);
- maxFd = asyncFd;
- }
-
-#if !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
- SocketMgr_GetSelectables(SOCKETMGR_IN,
- &sockReadFds,
- &numSockReadFds);
- for (index = 0; index < numSockReadFds; index++) {
- FD_SET(sockReadFds[index], &readFds);
- if (sockReadFds[index] > maxFd) {
- maxFd = sockReadFds[index];
- }
- }
-
- SocketMgr_GetSelectables(SOCKETMGR_OUT,
- &sockWriteFds,
- &numSockWriteFds);
- for (index = 0; index < numSockWriteFds; index++) {
- FD_SET(sockWriteFds[index], &writeFds);
- if (sockWriteFds[index] > maxFd) {
- maxFd = sockWriteFds[index];
- }
- }
-#endif
-
- tv.tv_sec = numUsecs / 1000000L;
- tv.tv_usec = numUsecs % 1000000L;
-
- status = select(maxFd + 1, &readFds, &writeFds, NULL, &tv);
-
- if (status == -1) {
- Debug("Select encountered an error: %s\n", strerror(errno));
- } else if (status > 0) {
- Debug("Select returned status > 0\n");
-
- if (curAsyncProc && FD_ISSET(asyncFd, &readFds)) {
- /* The async proc fd was written to */
-
- Bool ret;
-
- ASSERT(tdData->asyncProcCb);
-
- if (!ProcMgr_GetAsyncStatus(curAsyncProc, &ret)) {
- ret = FALSE;
- Debug("Failed to get return status for async process.\n");
- }
-
- tdData->asyncProcCb(ret, tdData->asyncProcCbData);
- Debug("Done executing asynchronous cmd\n");
-
- /* Reinitialize */
- curAsyncProc = NULL;
- }
-
-#if !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
- for (index = 0; index < numSockReadFds; index++) {
- if (FD_ISSET(sockReadFds[index], &readFds)) {
- SocketMgr_ProcessSelectable(sockReadFds[index], SOCKETMGR_IN);
- }
- }
-
- for (index = 0; index < numSockWriteFds; index++) {
- if (FD_ISSET(sockWriteFds[index], &writeFds)) {
- SocketMgr_ProcessSelectable(sockWriteFds[index], SOCKETMGR_OUT);
- }
- }
-#endif
- }
-
-#if !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
- free((void *) sockReadFds);
- free((void *) sockWriteFds);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdDaemon --
- *
- * Setup a TCLO channel with VMware, and run the event loop
- *
- * Return value:
- * TRUE on normal exit (when sent SIGTERM)
- * FALSE otherwise (detail is displayed)
- *
- * Side effects:
- * if a signal is trapped, gDaemonSignalPtr is given its value
- * & the method exits
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GuestdDaemon(GuestApp_Dict **pConfDict, // IN/OUT
- int *gDaemonSignalPtr) // IN/OUT
-{
- Bool guestInfoEnabled = FALSE;
- ToolsDaemon_Data *data = NULL;
- VmBackupSyncProvider *syncProvider = NULL;
-
- data = ToolsDaemon_Init(pConfDict, EXEC_LOG,
- GuestdExecuteHalt, pConfDict,
- GuestdExecuteReboot, pConfDict,
- NULL, NULL,
- NULL, NULL,
- NULL, NULL);
- if (!data) {
- Warning("Unable to start guestd.\n");
- goto out;
- }
-
- ASSERT(data->in);
-
- /* Set up the guest info 'server'. */
- if (!GuestInfoServer_Init(ToolsDaemonEventQueue)) {
- Warning("Unable to start guest info server.\n");
- } else {
- guestInfoEnabled = TRUE;
- GuestInfoServer_DisableDiskInfoQuery(
- GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_DISABLEQUERYDISKINFO));
- }
-
- /*
- * Start listening for VMX requests to create the upgrader.
- */
- RpcIn_RegisterCallback(data->in, "upgrader.create",
- GuestdCreateUpgrader, NULL);
-
- /*
- * Initialize the vmbackup subsystem, if it's supported in the current
- * platform.
- */
- syncProvider = VmBackup_NewSyncDriverProvider();
- if (syncProvider != NULL) {
- Bool loggingEnabled = GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_LOG);
- VmBackup_Init(data->in, ToolsDaemonEventQueue, syncProvider,
- loggingEnabled);
- } else {
- Debug("No vmBackup implementation available!\n");
- }
-
- /*
- * Event loop
- */
-
- for (;;) {
- int nr = 0;
- uint64 sleepUsecs = 0;
-
- nr = EventManager_ProcessNext(ToolsDaemonEventQueue, &sleepUsecs);
- if (nr != 1) {
- fprintf(stderr,
- "Unexpected end of the main loop: returned value is %d\n",
- nr);
- goto out;
- }
-
- /* Reap our zombie children. */
- waitpid(-1, NULL, WNOHANG);
-
- if (*gDaemonSignalPtr) {
- /*
- * We are in a well-known context: the processing of the previous
- * event is done, and we haven't started to process the next event.
- *
- * In particular, if the previous event handler executed a TCLO
- * command that ended up sending a signal to us, we are sure that the
- * reply message for that command has been crafted. So it is the right
- * time to stop 'in', which will send this last reply back to VMware.
- *
- * --hpreg
- */
-
- fprintf(stderr, "Interrupted by signal %d.\n\n", *gDaemonSignalPtr);
- goto out;
- }
-
- if (!ToolsDaemon_CheckReset(data, &sleepUsecs)) {
- goto out;
- }
- GuestdSleep(sleepUsecs, data);
- }
-
- NOT_REACHED();
-
-out:
- if (guestInfoEnabled) {
- GuestInfoServer_Cleanup();
- }
-
- if (syncProvider != NULL) {
- VmBackup_Shutdown(data->in);
- }
-
- if (data) {
- ToolsDaemon_Cleanup(data);
- }
-
- return *gDaemonSignalPtr == SIGTERM ? TRUE : FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdDaemonWrapper --
- *
- * Wrap the call to GuestdDaemon so the signal handler gets both set
- * & reset.
- *
- * Return value:
- * TRUE on success (never happens)
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GuestdDaemonWrapper(GuestApp_Dict **pConfDict) // IN
-{
- Bool returnVal;
- struct sigaction olds[ARRAYSIZE(cSignals)];
-
- gDaemonSignal = 0;
-
- /*
- * Do not check return value.
- * setsid() only fails if we are already process group leader.
- */
- setsid();
-
- if (Signal_SetGroupHandler(cSignals, olds, ARRAYSIZE(cSignals),
- GuestdDaemonSignal) == 0) {
- return FALSE;
- }
-
- returnVal = GuestdDaemon(pConfDict, &gDaemonSignal);
-
- if (Signal_ResetGroupHandler(cSignals, olds, ARRAYSIZE(cSignals)) == 0) {
- return FALSE;
- }
-
- return returnVal;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdAlreadyRunning --
- *
- * Check if there is an instance of guestd already running.
- *
- * Note that we used to use pgrep(1) but that approach produces false
- * positives when the init script that starts guestd has the same name as
- * the guestd binary, as is done for open-vm-tools packages.
- *
- * Return value:
- * TRUE if there is another guestd running.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GuestdAlreadyRunning(char const *pidFileName) // IN
-{
- FILE *pidFile = NULL;
- pid_t pid = 0;
-
- ASSERT(pidFileName);
-
- pidFile = fopen(pidFileName, "r");
- if (pidFile) {
- int ret;
- ret = fscanf(pidFile, "%"FMTPID"\n", &pid);
- fclose(pidFile);
- if (ret != 1) {
- return FALSE;
- }
-
- /*
- * XXX There is an assumption that if the process with pid is alive,
- * the process is just guestd. Actually the process name should be
- * also checked because it is possible that there is another process
- * with same pid. 2 reasons it is not checked. First we can not find
- * a cross-platform method to check the process name. Second is that
- * the possibility is very low in our case because the PID file should
- * always be with guestd process. Even user manually kills the guestd,
- * the PID file will also be removed. Perhaps longer term we should
- * add a function like System_GetProcessName(pid_t) to
- * bora-vmsoft/lib/system that will hide the platform-specific
- * messiness.
- */
- if (pid != getpid() && kill(pid, 0) == 0) {
- return TRUE;
- }
- /*
- * If process with pid is dead, the PID file will be removed. If pid
- * is same as getpid(), PID file will also be removed.
- */
- unlink(pidFileName);
- }
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestdUsage --
- *
- * Write an help message on stderr and exit
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-GuestdUsage(char const *prog, // IN: Name of this program
- int exitCode) // IN
-{
- fprintf(stderr,
- "Usage:\n"
- "\n"
- " %s --help\n"
- " Display this help message\n"
- "\n"
- " %s --cmd <command>\n"
- " Make the %s execute a command\n"
- "\n"
- " %s\n"
- " Run in daemon mode\n"
- "\n"
- " [--background <PID file>]\n"
- " Start in the background, and write the PID of the background\n"
- " process in a file.\n"
- "\n"
- " [--halt-command <command>]\n"
- " Command to use to halt the system.\n"
- " The default is \"%s\"\n"
- "\n"
- " [--reboot-command <command>]\n"
- " Command to use to reboot the system.\n"
- " The default is \"%s\"\n"
- "\n",
- prog, prog, PRODUCT_LINE_NAME, prog, CONFVAL_HALT_DEFAULT,
- CONFVAL_REBOOT_DEFAULT);
-
- exit(exitCode);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * main --
- *
- * Run the program: parse the command line and do the requested job
- *
- * Results:
- * Exit code
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-main(int argc, // IN: Number of command line arguments
- char **argv) // IN: Array of arguments
-{
- Bool retVal;
- Bool rpci;
- Bool help;
- char const *pidFile;
- GuestApp_Dict *confDict;
-
- int index;
- Bool parseOptions;
- const char *arguments[1];
- int argumentIndex;
- int expectedArgumentIndex;
-
- if (!VmCheck_IsVirtualWorld()) {
-#ifndef ALLOW_TOOLS_IN_FOREIGN_VM
- Warning("The VMware service must be run from within a virtual machine.\n");
- return 0;
-#else
- runningInForeignVM = TRUE;
-#endif
- }
-
- confDict = Conf_Load();
-
- /*
- * Parse the command line.
- *
- * We do it by hand because getopt() doesn't handle long options, and
- * getopt_long is a GNU extension --hpreg
- *
- * argv[0] is the program name, as usual
- */
-
- /*
- * Optional arguments
- */
-
- /* Default values */
- rpci = FALSE;
- help = FALSE;
- pidFile = NULL;
-
- argumentIndex = 0;
- parseOptions = TRUE;
- for (index = 1; index < argc; index++) {
- Bool isOption;
-
- if (parseOptions) {
- if (strcmp(argv[index], "--") == 0) {
- /*
- * Special options to specify the end of options (in order to pass
- * arguments that begin with '-'
- */
-
- parseOptions = FALSE;
- continue;
- }
-
- isOption = strncmp(argv[index], "-", 1) == 0;
- } else {
- isOption = FALSE;
- }
-
- if (isOption) {
- char const *option;
-
- option = argv[index] + 1;
-
- if (strcmp(option, "-cmd") == 0) {
- rpci = TRUE;
- } else if (strcmp(option, "-help") == 0) {
- help = TRUE;
- } else if (strcmp(option, "-background") == 0) {
- if (index + 1 == argc) {
- fprintf(stderr, "The \"%s\" option on the command line requires an "
- "argument.\n\n", option);
- GuestdUsage(argv[0], 1);
- }
-
- index++;
- pidFile = argv[index];
- } else if (strcmp(option, "-halt-command") == 0) {
- if (index + 1 == argc) {
- fprintf(stderr, "The \"%s\" option on the command line requires an "
- "argument.\n\n", option);
- GuestdUsage(argv[0], 1);
- }
-
- index++;
- GuestApp_SetDictEntry(confDict, CONFNAME_HALT, argv[index]);
- } else if (strcmp(option, "-reboot-command") == 0) {
- if (index + 1 == argc) {
- fprintf(stderr, "The \"%s\" option on the command line requires an "
- "argument.\n\n", option);
- GuestdUsage(argv[0], 1);
- }
-
- index++;
- GuestApp_SetDictEntry(confDict, CONFNAME_REBOOT, argv[index]);
- } else {
- fprintf(stderr, "Invalid \"%s\" option on the command line.\n\n", option);
- GuestdUsage(argv[0], 1);
- }
- } else {
- if (argumentIndex >= ARRAYSIZE(arguments)) {
- fprintf(stderr, "Too many mandatory argument(s) on the command line. The "
- "maximum is %"FMTSZ"u.\n\n", ARRAYSIZE(arguments));
- GuestdUsage(argv[0], 1);
- }
-
- arguments[argumentIndex++] = argv[index];
- }
- }
-
- /*
- * Mandatory arguments
- */
-
- if (rpci) {
- expectedArgumentIndex = 1;
- } else {
- expectedArgumentIndex = 0;
- }
-
- if (argumentIndex != expectedArgumentIndex) {
- fprintf(stderr, "Incorrect number of mandatory argument(s) "
- "on the command line: %u instead of %u.\n\n",
- argumentIndex, expectedArgumentIndex);
- GuestdUsage(argv[0], 1);
- }
-
- /*
- * Do the requested job
- */
-
- if (help) {
- GuestdUsage(argv[0], 0);
- }
-
- if (rpci) {
- return GuestdCommandLineRpci(arguments[0]) ? 0 : 1;
- }
-
-
- /*
- * We must (attempt to) check for another instance running, even when the
- * '--background <PID file>' option wasn't specified (fix for bug 8098).
- * In such cases, we'll assume that the PID file can be found at
- * DEFAULT_PIDFILE, which should work for Linux, Solaris, and FreeBSD guests.
- */
- if (GuestdAlreadyRunning(pidFile ? pidFile : DEFAULT_PIDFILE)) {
- fprintf(stderr, "Guestd is already running, exiting.\n");
- GuestApp_FreeDict(confDict);
- /*
- * Here we still should return 0 otherwise if vmware-tools.sh
- * get an error return, it will ask user to run config.pl
- * again. We should quit here silently.
- */
- exit(0);
- }
-
- if (pidFile) {
- if (!System_Daemon(FALSE, FALSE, pidFile)) {
- fprintf(stderr, "Unable to daemonize: %s\n", strerror(errno));
- GuestApp_FreeDict(confDict);
- exit(1);
- }
- }
-
- retVal = GuestdDaemonWrapper(&confDict) ? 0 : 1;
-
- if (pidFile) {
- unlink(pidFile);
- }
-
- GuestApp_FreeDict(confDict);
-
- return retVal;
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2001 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-
-/*
- * toolsDaemon.c --
- *
- * Platform independent methods used by the tools daemon.
- * The tools daemon does the following:
- * -starts automatically with the guest
- * -syncs the guest time to the host
- * -executes scripts on state change requests from the VMX
- * -listens for other TCLO cmds through the backdoor
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#ifdef _WIN32
-# include <windows.h>
-# include "win32u.h"
-# include "hgfsUsabilityLib.h"
-# include "rescaps.h"
-# include "ServiceHelpers.h"
-#endif
-
-
-#include "vmware.h"
-#include "toolsDaemon.h"
-#include "vm_version.h"
-#include "vm_app.h"
-#include "message.h"
-#include "eventManager.h"
-#include "debug.h"
-#include "guestApp.h"
-#include "rpcout.h"
-#include "rpcin.h"
-#include "hostinfo.h"
-#include "strutil.h"
-#include "str.h"
-#include "msg.h"
-#include "backdoor.h"
-#include "backdoor_def.h"
-#include "system.h"
-#include "netutil.h"
-#include "hgfsServerManager.h"
-#include "conf.h"
-#include "foundryToolsDaemon.h"
-#include "util.h"
-#include "vmcheck.h"
-#include "guestInfo.h"
-
-#ifndef N_PLAT_NLM
-#include "vm_atomic.h"
-#include "hostinfo.h"
-#include "guestInfoServer.h"
-#include "syncDriver.h"
-#endif // #ifndef N_PLAT_NLM
-
-#if !defined(__FreeBSD__) && !defined(sun) && !defined(N_PLAT_NLM)
-#include "deployPkg.h"
-#endif
-
-#ifdef TOOLSDAEMON_HAS_RESOLUTION
-# include "resolution.h"
-#endif
-
-/* in 1/100 of a second */
-#define RPCIN_POLL_TIME 10
-/* sync the time once a minute */
-#define TIME_SYNC_TIME 6000
-/* only PERCENT_CORRECTION percent is corrected everytime */
-#define PERCENT_CORRECTION 50
-
-/*
- * Table mapping state changes to their conf file names.
- */
-/*
- * Bug 294328: Mac OS guests do not (yet) support the state change RPCs.
- */
-#ifndef __APPLE__
-static const char *stateChgConfNames[] = {
- NULL, /* NONE */
- CONFNAME_POWEROFFSCRIPT, /* HALT */
- CONFNAME_POWEROFFSCRIPT, /* REBOOT */
- CONFNAME_POWERONSCRIPT, /* POWERON */
- CONFNAME_RESUMESCRIPT, /* RESUME */
- CONFNAME_SUSPENDSCRIPT, /* SUSPEND */
-};
-#endif
-
-DblLnkLst_Links *ToolsDaemonEventQueue = NULL; // main loop event queue
-static char *guestTempDirectory = NULL;
-
-void ToolsDaemon_InitializeForeignVM(ToolsDaemon_Data *toolsDaemonData);
-void ToolsDaemon_ShutdownForeignVM(void);
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_SyncTime --
- *
- * Set the guest OS time to the host OS time
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-ToolsDaemon_SyncTime(Bool slewCorrection, // IN: Is clock slewing enabled?
- Bool syncOnce, // IN: Is this function called in a loop?
- void *toolsData) // IN: Opaque data
-{
- Backdoor_proto bp;
- int64 maxTimeLag;
- int64 interruptLag;
- int64 guestSecs;
- int64 guestUsecs;
- int64 hostSecs;
- int64 hostUsecs;
- int64 diffSecs;
- int64 diffUsecs;
- int64 diff;
- ToolsDaemon_Data *data = (ToolsDaemon_Data *) toolsData;
- Bool timeLagCall = FALSE;
-#ifdef VMX86_DEBUG
- static int64 lastHostSecs = 0;
- int64 secs1, usecs1;
- int64 secs2, usecs2;
-
- System_GetCurrentTime(&secs1, &usecs1);
-#endif
-
- Debug("Daemon: Synchronizing time\n");
-
- /*
- * We need 3 things from the host, and there exist 3 different versions of
- * the calls (described further below):
- * 1) host time
- * 2) maximum time lag allowed (config option), which is a
- * threshold that keeps the tools from being over eager about
- * resetting the time when it is only a little bit off.
- * 3) interrupt lag
- *
- * First 2 versions of the call add interrupt lag to the maximum allowed
- * time lag, where as in the last call it is returned separately.
- *
- * Three versions of the call:
- *
- * - BDOOR_CMD_GETTIME: suffers from a 136-year overflow problem that
- * cannot be corrected without breaking backwards compatibility with
- * older Tools. So, we have the newer BDOOR_CMD_GETTIMEFULL, which is
- * overflow safe.
- *
- * - BDOOR_CMD_GETTIMEFULL: overcomes the problem above.
- *
- * - BDOOR_CMD_GETTIMEFULL_WITH_LAG: Both BDOOR_CMD_GETTIMEFULL and
- * BDOOR_CMD_GETTIME returns max lag limit as interrupt lag + the maximum
- * allowed time lag. BDOOR_CMD_GETTIMEFULL_WITH_LAG separates these two
- * values. This is helpful when synchronizing time backwards by slewing
- * the clock.
- *
- * We use BDOOR_CMD_GETTIMEFULL_WITH_LAG first and fall back to
- * BDOOR_CMD_GETTIMEFULL or BDOOR_CMD_GETTIME.
- *
- * Note that BDOOR_CMD_GETTIMEFULL and BDOOR_CMD_GETTIMEFULL_WITH_LAG will
- * not touch EAX when it succeeds. So we check for errors by comparing EAX to
- * BDOOR_MAGIC, which was set by the call to Backdoor() prior to touching the
- * backdoor port.
- */
- bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL_WITH_LAG;
- Backdoor(&bp);
- if (bp.out.ax.word == BDOOR_MAGIC) {
- hostSecs = ((uint64)bp.out.si.word << 32) | bp.out.dx.word;
- interruptLag = bp.out.di.word;
- timeLagCall = TRUE;
- Debug("Using BDOOR_CMD_GETTIMEFULL_WITH_LAG\n");
- } else {
- Debug("BDOOR_CMD_GETTIMEFULL_WITH_LAG not supported by current host, attempting "
- "BDOOR_CMD_GETTIMEFULL\n");
- interruptLag = 0;
- bp.in.cx.halfs.low = BDOOR_CMD_GETTIMEFULL;
- Backdoor(&bp);
- if (bp.out.ax.word == BDOOR_MAGIC) {
- hostSecs = ((uint64)bp.out.si.word << 32) | bp.out.dx.word;
- } else {
- Debug("BDOOR_CMD_GETTIMEFULL not supported by current host, attempting "
- "BDOOR_CMD_GETTIME\n");
- bp.in.cx.halfs.low = BDOOR_CMD_GETTIME;
- Backdoor(&bp);
- hostSecs = bp.out.ax.word;
- }
- }
- hostUsecs = bp.out.bx.word;
- maxTimeLag = bp.out.cx.word;
-
- if (hostSecs <= 0) {
- Warning("Invalid host OS time: %"FMT64"d secs, %"FMT64"d usecs.\n\n",
- hostSecs, hostUsecs);
-
- return FALSE;
- }
-
- /* Get the guest OS time */
- if (!System_GetCurrentTime(&guestSecs, &guestUsecs)) {
- Warning("Unable to retrieve the guest OS time: %s.\n\n", Msg_ErrString());
- return FALSE;
- }
-
- diffSecs = hostSecs - guestSecs;
- diffUsecs = hostUsecs - guestUsecs;
- if (diffUsecs < 0) {
- diffSecs -= 1;
- diffUsecs += 1000000U;
- }
- diff = diffSecs * 1000000L + diffUsecs;
-
-#ifdef VMX86_DEBUG
- Debug("Daemon: Guest clock lost %.6f secs; limit=%.2f; "
- "%"FMT64"d secs since last update\n",
- diff / 1000000.0, maxTimeLag / 1000000.0, hostSecs - lastHostSecs);
- Debug("Daemon: %d, %d, %"FMT64"d, %"FMT64"d, %"FMT64"d.\n",
- syncOnce, slewCorrection, diff, maxTimeLag, interruptLag);
- lastHostSecs = hostSecs;
-#endif
-
- if (syncOnce) {
- /*
- * Non-loop behavior:
- *
- * Perform a step correction if:
- * 1) The guest OS is behind the host OS by more than maxTimeLag + interruptLag.
- * 2) The guest OS is ahead of the host OS.
- */
- if (diff > maxTimeLag + interruptLag) {
- System_DisableTimeSlew();
- if (!System_AddToCurrentTime(diffSecs, diffUsecs)) {
- Warning("Unable to set the guest OS time: %s.\n\n", Msg_ErrString());
- return FALSE;
- }
- }
- } else {
-
- /*
- * Loop behavior:
- *
- * If guest is behind host by more than maxTimeLag + interruptLag
- * perform a step correction to the guest clock and ask the monitor
- * to drop its accumulated catchup (interruptLag).
- *
- * Otherwise, perform a slew correction. Adjust the guest's clock
- * rate to be either faster or slower than nominal real time, such
- * that we expect to correct correctionPercent percent of the error
- * during this synchronization cycle.
- */
-
- if (diff > maxTimeLag + interruptLag) {
- System_DisableTimeSlew();
- if (!System_AddToCurrentTime(diffSecs, diffUsecs)) {
- Warning("Unable to set the guest OS time: %s.\n\n", Msg_ErrString());
- return FALSE;
- }
- } else if (slewCorrection && timeLagCall) {
- int64 slewDiff;
-
- /* Don't consider interruptLag during clock slewing. */
- slewDiff = diff - interruptLag;
-
- /* Correct only data->slewPercentCorrection percent error. */
- slewDiff = (data->slewPercentCorrection * slewDiff) / 100;
-
- if (!System_EnableTimeSlew(slewDiff, data->timeSyncPeriod)) {
- Warning("Unable to slew the guest OS time: %s.\n\n", Msg_ErrString());
- return FALSE;
- }
- } else {
- System_DisableTimeSlew();
- }
- }
-
-#ifdef VMX86_DEBUG
- System_GetCurrentTime(&secs2, &usecs2);
-
- Debug("Time changed from %"FMT64"d.%"FMT64"d -> %"FMT64"d.%"FMT64"d\n",
- secs1, usecs1, secs2, usecs2);
-#endif
-
- /*
- * If we have stepped the time, ask TimeTracker to reset to normal the rate
- * of timer interrupts it forwards from the host to the guest.
- */
- if (!System_IsTimeSlewEnabled()) {
- bp.in.cx.halfs.low = BDOOR_CMD_STOPCATCHUP;
- Backdoor(&bp);
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonConfFileLoop --
- *
- * Run the "conf file reload" loop
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonConfFileLoop(void *clientData) // IN
-{
- GuestApp_Dict **pConfDict = (GuestApp_Dict **) clientData;
-
- ASSERT(pConfDict);
-
- /*
- * With the addition of the Sync Driver we can get into a state
- * where the system drive is frozen, preventing the completion of
- * any disk-based I/O. The event that periodically reloads the conf
- * file then gets blocked, which blocks the main daemon thread and
- * prevents any further GuestRPC messages from getting
- * processed. This effectively deadlocks the tools daemon and among
- * other things makes it impossible to thaw disk I/O once it's been
- * frozen.
- *
- * So, we keep track of when the disks are frozen and skip doing disk
- * I/O during that time.
- */
-#if !defined(N_PLAT_NLM)
- if (!SyncDriver_DrivesAreFrozen()) {
- if (Conf_ReloadFile(pConfDict)) {
- GuestInfoServer_DisableDiskInfoQuery(
- GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_DISABLEQUERYDISKINFO));
-
- Debug_Set(GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_LOG),
- DEBUG_PREFIX);
- Debug_EnableToFile(GuestApp_GetDictEntry(*pConfDict, CONFNAME_LOGFILE),
- FALSE);
- }
- }
-#else
- if (Conf_ReloadFile(pConfDict)) {
- Debug_Set(GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_LOG),
- DEBUG_PREFIX);
- Debug_EnableToFile(GuestApp_GetDictEntry(*pConfDict, CONFNAME_LOGFILE),
- FALSE);
- }
-#endif
-
- EventManager_Add(ToolsDaemonEventQueue, CONF_POLL_TIME, ToolsDaemonConfFileLoop,
- pConfDict);
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonTimeSyncLoop --
- *
- * Run the "time synchronization" loop
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonTimeSyncLoop(void *clientData) // IN
-{
- ToolsDaemon_Data *data = (ToolsDaemon_Data *)clientData;
-
- ASSERT(data);
-
- /* The event has fired: it is no longer valid */
- data->timeSyncEvent = NULL;
-
- if (!data->timeSyncPeriod) {
- data->timeSyncPeriod = TIME_SYNC_TIME;
- }
- if (!ToolsDaemon_SyncTime(data->slewCorrection, FALSE, clientData)) {
- Warning("Unable to synchronize time.\n\n");
- return FALSE;
- }
-
- data->timeSyncEvent = EventManager_Add(ToolsDaemonEventQueue, data->timeSyncPeriod,
- ToolsDaemonTimeSyncLoop, data);
- if (data->timeSyncEvent == NULL) {
- Warning("Unable to run the \"time synchronization\" loop.\n\n");
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonDisableWinTimeDaemon --
- *
- * Try to disable the Windows Time Daemon.
- *
- * Results:
- * TRUE on success
- * FALSE on failure
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(_WIN32)
-static Bool
-ToolsDaemonDisableWinTimeDaemon(void)
-{
- DWORD timeAdjustment;
- DWORD timeIncrement;
- DWORD error;
- BOOL timeAdjustmentDisabled;
- BOOL success = FALSE;
-
- /*
- * We need the SE_SYSTEMTIME_NAME privilege to make the change; get
- * the privilege now (or bail if we can't).
- */
- success = System_SetProcessPrivilege(SE_SYSTEMTIME_NAME, TRUE);
- if (!success) {
- return FALSE;
- }
-
- /* Actually try to stop the time daemon. */
- if (GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
- &timeAdjustmentDisabled)) {
- Debug("GetSystemTimeAdjustment() succeeded: timeAdjustment %d,"
- "timeIncrement %d, timeAdjustmentDisabled %s\n",
- timeAdjustment, timeIncrement,
- timeAdjustmentDisabled ? "TRUE" : "FALSE");
- /*
- * timeAdjustmentDisabled means the opposite of what you'd think;
- * if it's TRUE, that means the system may be adjusting the time
- * on its own using the time daemon. Read MSDN for the details,
- * and see Bug 24173 for more discussion on this.
- */
-
- if (timeAdjustmentDisabled) {
- /*
- * MSDN is a bit vague on the semantics of this function, but it
- * would appear that the timeAdjustment value here is simply the
- * total amount that the system will add to the clock on each
- * timer tick, i.e. if you set it to zero the system clock will
- * not progress at all (and indeed, attempting to set it to zero
- * results in an ERROR_INVALID_PARAMETER). In order to have time
- * proceed at the normal rate, this needs to be set to the value
- * of timeIncrement retrieved from GetSystemTimeAdjustment().
- */
- if (!SetSystemTimeAdjustment(timeIncrement, FALSE)) {
- error = GetLastError();
- Debug("Daemon: SetSystemTimeAdjustment failed: %d\n", error);
- goto exit;
- }
- }
- } else {
- error = GetLastError();
- Debug("Daemon: GetSystemTimeAdjustment failed: %d\n", error);
- goto exit;
- }
-
- success = TRUE;
-
- exit:
- Debug("Stopping time daemon %s.\n", success ? "succeeded" : "failed");
- System_SetProcessPrivilege(SE_SYSTEMTIME_NAME, FALSE);
- return success;
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonStartStopTimeSyncLoop --
- *
- * Start or stop the "time synchronization" loop. Nothing will be
- * done if start==TRUE & it's already running or start=FALSE & it's
- * not running.
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonStartStopTimeSyncLoop(ToolsDaemon_Data *data, // IN
- Bool start) // IN
-{
- ASSERT(data);
-
- if (start && data->timeSyncEvent == NULL) {
- Debug("Daemon: Starting time sync loop\n");
- Debug("Daemon: New sync period is %d sec\n", data->timeSyncPeriod);
- if (!ToolsDaemonTimeSyncLoop(data)) {
- return FALSE;
- }
-
-#if defined(_WIN32)
- Debug("Daemon: Attempting to disable Windows Time daemon\n");
- if (!ToolsDaemonDisableWinTimeDaemon()) {
- Debug("Daemon: Failed to disable Windows Time daemon\n");
- }
-#endif
-
- return TRUE;
- } else if (!start && data->timeSyncEvent != NULL) {
- Debug("Daemon: Stopping time sync loop\n");
- System_DisableTimeSlew();
- EventManager_Remove(data->timeSyncEvent);
- data->timeSyncEvent = NULL;
-
- return TRUE;
- } else {
- /*
- * No need to start time sync b/c it's already running or no
- * need to stop it b/c it's not running.
- */
- return TRUE;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonOldUpdateOptions --
- *
- * Get the latest value of the tools options from VMware, and update
- * guestd's behavior according to this new value
- * (Legacy from before the unified TCLO loop)
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonOldUpdateOptions(ToolsDaemon_Data *data) // IN
-{
- uint32 toolsOptions;
- Bool syncTime;
- Bool copyPaste;
- Bool autoHide;
-
- ASSERT(data);
-
- toolsOptions = GuestApp_OldGetOptions();
-
- syncTime = (toolsOptions & VMWARE_GUI_SYNC_TIME) != 0;
- GuestApp_SetDictEntry(data->optionsDict, TOOLSOPTION_SYNCTIME,
- syncTime ? "1" : "0");
- copyPaste = (toolsOptions & VMWARE_GUI_EXCHANGE_SELECTIONS) != 0;
- GuestApp_SetDictEntry(data->optionsDict, TOOLSOPTION_COPYPASTE,
- copyPaste ? "1" : "0");
- autoHide = (toolsOptions & VMWARE_GUI_WARP_CURSOR_ON_UNGRAB) != 0;
- GuestApp_SetDictEntry(data->optionsDict, TOOLSOPTION_AUTOHIDE,
- autoHide ? "1" : "0");
-
- if (ToolsDaemonStartStopTimeSyncLoop(data, syncTime) == FALSE) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonOldUpdateOptionsLoop --
- *
- * Run the "update options" loop
- * (Legacy from before the unified TCLO loop)
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonOldUpdateOptionsLoop(void *clientData) // IN
-{
- ToolsDaemon_Data *data = (ToolsDaemon_Data *)clientData;
-
- ASSERT(data);
-
- if (ToolsDaemonOldUpdateOptions(data) == FALSE) {
- return FALSE;
- }
-
- data->oldOptionsLoop = EventManager_Add(ToolsDaemonEventQueue, 100,
- ToolsDaemonOldUpdateOptionsLoop, data);
- if (data->oldOptionsLoop == NULL) {
- Warning("Unable to run the \"update options\" loop.\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonStartStopOldUpdateOptionsLoop --
- *
- * Start or stop the old upate options loop depending
- * on whether vmware is unified loop capable.
- * It won't be started again it's already running & it won't be
- * stopped if it's not running.
- *
- * Results:
- * TRUE on success
- * FALSE if all attempts to get options have failed.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonStartStopOldUpdateOptionsLoop(ToolsDaemon_Data *data) // IN
-{
- Bool unifiedLoopCap;
-
- ASSERT(data);
-
- /*
- * Start the old options loop if it's not running & the unified loop is no
- * supported; stop it if it is running & the unified loop is supported.
- */
- unifiedLoopCap = GuestApp_GetUnifiedLoopCap(TOOLS_DAEMON_NAME);
- if (!unifiedLoopCap && data->oldOptionsLoop == NULL) {
- Debug("Daemon: No unified loop cap; starting old poll loop.\n");
-
- if (!ToolsDaemonOldUpdateOptionsLoop(data)) {
- return FALSE;
- }
- } else if (unifiedLoopCap && data->oldOptionsLoop != NULL) {
- Debug("Daemon: Unified loop cap found; stopping old poll loop.\n");
-
- EventManager_Remove(data->oldOptionsLoop);
- data->oldOptionsLoop = NULL;
- } else {
- /*
- * No need to start the loop b/c it's already running or no
- * need to stop it b/c it's not running.
- */
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonResetSent --
- *
- * Called after we've sent the reset TCLO completion to vmware.
- *
- * Results:
- * TRUE on success
- * FALSE on failure
- *
- * Side effects:
- * Set our version in vmware & start/stop the old options loop.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonResetSent(void *clientData) // IN
-{
- ToolsDaemon_Data *data = (ToolsDaemon_Data *)clientData;
-
- ASSERT(data);
-
-#if !defined(N_PLAT_NLM)
- GuestInfoServer_VMResumedNotify();
-#endif
-
- GuestApp_Log("Version: " BUILD_NUMBER "\n");
-
- if (!ToolsDaemonStartStopOldUpdateOptionsLoop(data)) {
- /* We aren't much use if we can't get the options */
- Panic("Unable to get options from %s\n", PRODUCT_LINE_NAME);
- }
-
- if (data->resetCB) {
- data->resetCB(data->resetCBData);
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonTcloReset --
- *
- * 'reset' tclo cmd handler. MUST be the first tclo message sent
- * by VMware when it recognizes that a toolbox app has opened
- * a tclo channel.
- *
- * Results:
- * TRUE on success (*result is empty)
- * FALSE on failure (*result contains the error)
- *
- * Side effects:
- * May start or stop the old update options loop.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonTcloReset(RpcInData *data) // IN/OUT
-{
- /*
- * Mandatory reset RPC
- */
-
- Debug("----------Daemon: Received 'reset' from vmware\n");
-
- /*
- * Schedule the post-reset actions to happen a little after one cycle of the
- * RpcIn loop. This will give vmware a chance to receive the ATR &
- * reinitialize the channel if appropriate. [greg]
- */
- EventManager_Add(ToolsDaemonEventQueue, (int) (RPCIN_POLL_TIME * 1.5),
- ToolsDaemonResetSent, data->clientData);
-
- return RPCIN_SETRETVALS(data, "ATR " TOOLS_DAEMON_NAME, TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonStateChangeDone --
- *
- * Called when a state change script is done running.
- * Sends the state change status with the script exit value.
- *
- * Results:
- * None
- *
- * Side effects:
- * May halt/reboot the VM. Also VMware may suspend the VM upon
- * receipt of a positive status.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-ToolsDaemonStateChangeDone(Bool status, // IN
- void *cbData) // IN
-{
- ToolsDaemon_Data *data = (ToolsDaemon_Data *) cbData;
-
- ASSERT(data);
- ASSERT(data->rebootCB);
- ASSERT(data->haltCB);
-
- Debug("Daemon: state change callback called\n");
-
- /*
- * We execute the requested action if the script succeeded, or if the
- * same action was tried before but didn't finish due to a script failure.
- * See bug 168568 for discussion.
- */
- if (status || data->lastFailedStateChg == data->stateChgInProgress) {
- status = TRUE;
-#ifdef _WIN32
- if (data->stateChgInProgress == GUESTOS_STATECHANGE_REBOOT || data->stateChgInProgress == GUESTOS_STATECHANGE_HALT) {
- if (Hostinfo_GetOSType() >= OS_VISTA) {
- DISABLE_RES_CAPS();
- }
- }
-#endif
- if (data->stateChgInProgress == GUESTOS_STATECHANGE_REBOOT) {
- Debug("Initiating reboot\n");
- status = data->rebootCB(data->rebootCBData);
- } else if (data->stateChgInProgress == GUESTOS_STATECHANGE_HALT) {
- Debug("Initiating halt\n");
- status = data->haltCB(data->haltCBData);
- }
- data->lastFailedStateChg = GUESTOS_STATECHANGE_NONE;
- }
-
- if (!status) {
- data->lastFailedStateChg = data->stateChgInProgress;
- }
-
- if (!ToolsDaemon_SetOsPhase(status, data->stateChgInProgress)) {
- Warning("Unable to send the status RPCI");
- }
-
- data->stateChgInProgress = GUESTOS_STATECHANGE_NONE;
-
- /* Unless the process couldn't be spawned, we need to free it */
- if (data->asyncProc) {
- free(data->asyncProc);
- data->asyncProc = NULL;
- }
-}
-
-
-/*
- * Bug 294328: Mac OS guests do not (yet) support the state change RPCs.
- */
-#ifndef __APPLE__
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonTcloStateChange --
- *
- * Tclo cmd handler for commands which invoke state change scripts.
- *
- * Results:
- * TRUE on success (*result is empty)
- * FALSE on failure (*result contains the error)
- *
- * Side effects:
- * Scripts are invoked in the guest.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonTcloStateChange(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- size_t argsSize, // Ignored
- void *clientData) // IN
-{
- int i;
- ProcMgr_ProcArgs procArgs;
- ToolsDaemon_Data *data = (ToolsDaemon_Data *)clientData;
-
- ASSERT(data);
- ASSERT(data->pConfDict);
- ASSERT(*data->pConfDict);
-
- Debug("Got state change message\n");
-
- if (data->asyncProc != NULL) {
- Debug("State change already in progress\n");
- return RpcIn_SetRetVals(result, resultLen,
- "State change already in progress", FALSE);
- }
-
- for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) {
- if (strcmp(name, stateChangeCmdTable[i].tcloCmd) == 0) {
- char *script;
- char *scriptCmd;
- unsigned int stateId;
-
- stateId = stateChangeCmdTable[i].id;
- data->stateChgInProgress = (GuestOsState)stateId;
-
- /* Check for the toolScripts option. */
- if (!data->toolScriptOption[stateId]) {
- ToolsDaemonStateChangeDone(TRUE, data);
- Debug("Script for %s not configured to run\n", stateChangeCmdTable[i].tcloCmd);
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
- }
-
- script = Util_SafeStrdup(GuestApp_GetDictEntry(*data->pConfDict,
- stateChgConfNames[stateId]));
- Debug("Script to execute is: %s\n", script);
- if (strlen(script) == 0) {
- ToolsDaemonStateChangeDone(TRUE, data);
- Debug("No script to run\n");
- free(script);
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
- } else if (!Util_IsAbsolutePath(script)) {
- char *absScript;
- char *installDir = GuestApp_GetInstallPath();
- ASSERT_MEM_ALLOC(installDir);
- absScript = Str_Asprintf(NULL, "%s%c%s", installDir, DIRSEPC, script);
- ASSERT_MEM_ALLOC(absScript);
- free(script);
- script = absScript;
- }
-#ifdef N_PLAT_NLM
- procArgs = NULL;
- scriptCmd = Str_Asprintf(NULL, "%s", script);
-#elif !defined(_WIN32)
- procArgs = NULL;
- ASSERT(data->execLogPath);
- scriptCmd = Str_Asprintf(NULL, "(%s) 2>&1 >> %s",
- script, data->execLogPath);
-#else
- /*
- * Pass the CREATE_NO_WINDOW flag to CreateProcess so that the
- * cmd.exe window will not be visible to the user in the guest.
- */
- memset(&procArgs, 0, sizeof procArgs);
- procArgs.bInheritHandles = TRUE;
- procArgs.dwCreationFlags = CREATE_NO_WINDOW;
-
- {
- char systemDir[1024 * 3];
- Win32U_GetSystemDirectory(systemDir, sizeof systemDir);
- scriptCmd = Str_Asprintf(NULL, "%s\\cmd.exe /c \"%s\"", systemDir, script);
- }
-#endif
-
- if (scriptCmd == NULL) {
- Debug("Could not format the cmd to run scripts\n");
- return RpcIn_SetRetVals(result, resultLen,
- "Could not format cmd to run scritps",
- FALSE);
- }
- data->asyncProc = ProcMgr_ExecAsync(scriptCmd, &procArgs);
-
- if (data->asyncProc) {
- data->asyncProcCb = ToolsDaemonStateChangeDone;
- data->asyncProcCbData = data;
- } else {
- ToolsDaemonStateChangeDone(FALSE, data);
- goto startError;
- }
-
- free(script);
- free(scriptCmd);
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-
- startError:
- free(script);
- free(scriptCmd);
- Debug("Error starting script\n");
- return RpcIn_SetRetVals(result, resultLen, "Error starting script",
- FALSE);
- }
- }
-
- Debug("Invalid state change command\n");
- return RpcIn_SetRetVals(result, resultLen, "Invalid state change command",
- FALSE);
-}
-#endif // ifndef __APPLE__
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonTcloCapReg --
- *
- * Register our capabilities with the VMX & request
- *
- * Return value:
- * TRUE on success
- * FALSE on failure
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonTcloCapReg(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- size_t argsSize, // Ignored
- void *clientData) // IN
-{
-#ifdef _WIN32
- unsigned int minResolutionWidth;
- unsigned int minResolutionHeight;
-#endif
- ToolsDaemon_Data *data;
- uint32 version;
-
- data = (ToolsDaemon_Data *)clientData;
- ASSERT(data);
-
-#ifdef _WIN32
- /*
- * Inform the VMX that we support setting the guest
- * resolution and display topology. Currently, this only
- * applies on windows.
- */
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.resolution_set 1")) {
- Debug("ToolsDaemonTcloCapReg: Unable to register resolution set capability\n");
- }
- /* Tell the VMX to send resolution updates to the tools daemon */
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.resolution_server %s 1",
- TOOLS_DAEMON_NAME)) {
- Debug("ToolsDaemonTcloCapReg: Unable to register resolution server capability\n");
- }
- /*
- * Bug 149541: Windows 2000 does not currently support multimon.
- *
- * In addition, NT will never support multimon. 9x guests have
- * frozen tools, and will report this capability set to 1, which
- * current UIs will treat as unsupported.
- */
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.display_topology_set %s",
- Hostinfo_GetOSType() >= OS_WINXP ? "2" : "0")) {
- Debug("ToolsDaemonTcloCapReg: Unable to register display topology set "
- "capability\n");
- }
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.display_global_offset 1")) {
- Debug("ToolsDaemonTcloCapReg: Unable to register display global offset "
- "capability\n");
- }
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.color_depth_set 1")) {
- Debug("ToolsDaemonTcloCapReg: Unable to register color depth set "
- "capability\n");
- }
-
- /*
- * Report to the VMX any minimum guest resolution below which we
- * can't resize the guest. See bug 58681.
- */
- ToolsDaemon_GetMinResolution(*data->pConfDict, &minResolutionWidth,
- &minResolutionHeight);
-
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.resolution_min %u %u",
- minResolutionWidth, minResolutionHeight)) {
- Debug("ToolsDaemonTcloCapReg: Unable to register minimum resolution of %ux%u\n",
- minResolutionWidth, minResolutionHeight);
- }
-#endif
-
-#ifdef TOOLSDAEMON_HAS_RESOLUTION
- Resolution_RegisterCaps();
-#endif
-
- /*
- * Bug 294328: Mac OS guests do not (yet) support the state change RPCs.
- */
-#ifndef __APPLE__
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.statechange")) {
- Debug("ToolsDaemonTcloCapReg: VMware doesn't support tools.capability.statechange. "
- "Trying .haltreboot\n");
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.haltreboot")) {
- return RpcIn_SetRetVals(result, resultLen,
- "Unable to register capabilities", FALSE);
- }
- }
-
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.softpowerop_retry")) {
- Debug("ToolsDaemonTcloCapReg: VMX doesn't support "
- "tools.capability.softpowerop_retry.");
- }
-#endif // ifndef __APPLE__
-
-/*
- * This is a _WIN32 || linux check, with the additional check since linux is
- * defined when you build the NetWare Tools.
- */
-#if (defined(_WIN32) || defined(linux)) && !defined(N_PLAT_NLM)
- {
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.auto_upgrade 2")) {
- Debug("ToolsDaemonTcloCapReg: Unable to register "
- "auto-upgrading capability.\n");
- }
-
- if (guestTempDirectory == NULL) {
-#ifdef _WIN32
- guestTempDirectory = File_GetTmpDir(FALSE);
-#else
- guestTempDirectory = Util_GetSafeTmpDir(FALSE);
-#endif
- }
-
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.guest_temp_directory 1 %s",
- guestTempDirectory)) {
- Debug("ToolsDaemonTcloCapReg: Unable to register guest temp "
- "directory capability.\n");
- }
- }
-#endif
-
-#if !defined(N_PLAT_NLM)
- {
- char *confPath = GuestApp_GetConfPath();
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.guest_conf_directory %s",
- confPath ? confPath : "")) {
- Debug("ToolsDaemonTcloCapReg: Unable to register guest conf "
- "directory capability.\n");
- }
- free(confPath);
- }
-
- /*
- * Send the uptime here so that the VMX can detect soft resets. This must be
- * sent before the Tools version RPC since the version RPC handler uses the
- * uptime to detect soft resets.
- */
- if (!GuestInfoServer_SendUptime()) {
- Debug("Daemon: Error setting guest uptime during 'reset' request.\n");
- }
-#endif
-
- /*
- * Send the monolithic Tools version. Using a configuration option, users
- * can override the Tools version such that the VMX treats the Tools as not
- * to be managed by the VMware platform.
- */
-#if defined(OPEN_VM_TOOLS)
- version = TOOLS_VERSION_UNMANAGED;
-#else
- version = GuestApp_GetDictEntryBool(*data->pConfDict,
- CONFNAME_DISABLETOOLSVERSION) ?
- TOOLS_VERSION_UNMANAGED : TOOLS_VERSION_CURRENT;
-#endif
- if (!RpcOut_sendOne(NULL, NULL, "tools.set.version %u", version)) {
- Debug("Daemon: Error setting tools version during 'Capabilities_Register'"
- "request.\n");
- }
-
-#if !defined(N_PLAT_NLM) && !defined(sun)
- if (!HgfsServerManager_CapReg(TOOLS_DAEMON_NAME, TRUE)) {
- Debug("ToolsDaemonTcloCapReg: Failed to register HGFS server capability.\n");
- }
-#endif
-
-#if defined(WIN32)
- HgfsUsability_RegisterServiceCaps();
- if (Hostinfo_GetOSType() >= OS_VISTA) {
- ServiceHelpers_SendResolutionCaps();
- }
-#endif
-
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonTcloTimeSync --
- *
- * Sync the guest's time with the host's.
- *
- * Return value:
- * TRUE on success
- * FALSE on failure
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonTcloTimeSync(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- size_t argsSize, // Ignored
- void *clientData) // Ignored
-{
- Bool slewCorrection = !strcmp(args, "1");
-
- if (!ToolsDaemon_SyncTime(slewCorrection, TRUE, clientData)) {
- return RpcIn_SetRetVals(result, resultLen,
- "Unable to sync time", FALSE);
- } else {
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonTcloSetOption --
- *
- * Parse a "Set_Option" TCLO cmd from the VMX & update the local
- * value of the option.
- *
- * Return value:
- * TRUE if the set option command was executed
- * FALSE if something failed (detail displayed)
- *
- * Side effects:
- * Start or stop processes (like time syncing) that could be affected
- * by option's new value.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-ToolsDaemonTcloSetOption(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- size_t argsSize, // Ignored
- void *clientData) // IN
-{
- Bool retVal = FALSE;
- char *option;
- char *value;
- unsigned int index = 0;
- static Bool timeSyncStartup = TRUE;
- static int oldTimeSyncValue = -1;
-
- ToolsDaemon_Data *data = (ToolsDaemon_Data *)clientData;
-
- ASSERT(data);
-
- /* parse the option & value string */
- option = StrUtil_GetNextToken(&index, args, " ");
- index++; // ignore leading space before value
- value = StrUtil_GetNextToken(&index, args, "");
- if (option == NULL || value == NULL || strlen(value) == 0) {
- goto invalid_option;
- }
-
- /* Validate the option name & value */
- if (strcmp(option, TOOLSOPTION_SYNCTIME) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_SLEWCORRECTION) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERCENTCORRECTION) == 0) {
- int32 percent;
- if (!StrUtil_StrToInt(&percent, value) || percent == 0 || percent > 100) {
- goto invalid_value;
- }
- Debug("Daemon: update the slew correction percent.\n");
- } else if (strcmp(option, TOOLSOPTION_COPYPASTE) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_AUTOHIDE) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_BROADCASTIP) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERIOD) == 0) {
- Debug("Daemon: update the time sync period.\n");
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_ENABLE) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_STARTUP) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_LINK_ROOT_HGFS_SHARE) == 0) {
- /*
- * Check to make sure that we actually support creating the link
- * on this platform.
- */
- if (!data->linkHgfsCB || !data->unlinkHgfsCB) {
- goto invalid_option;
- }
-
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWERON) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWEROFF) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_SUSPEND) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_RESUME) == 0) {
- if (strcmp(value, "1") != 0 && strcmp(value, "0") != 0) {
- goto invalid_value;
- }
- } else {
- goto invalid_option;
- }
-
- Debug("Daemon: Setting option '%s' to '%s'\n", option, value);
- GuestApp_SetDictEntry(data->optionsDict, option, value);
-
- /* Take action that may be necessary given the new value */
- if (strcmp(option, TOOLSOPTION_SYNCTIME) == 0) {
- int start = (strcmp(value, "1") == 0);
-
- /*
- * Try the one-shot time sync if time sync transitions from
- * 'off' to 'on'.
- */
- if (oldTimeSyncValue == 0 && start &&
- GuestApp_GetDictEntry(data->optionsDict, TOOLSOPTION_SYNCTIME_ENABLE)) {
- ToolsDaemon_SyncTime(data->slewCorrection, TRUE, clientData);
- }
- oldTimeSyncValue = start;
-
- /* Now start/stop the loop. */
- if (!ToolsDaemonStartStopTimeSyncLoop(data, start)) {
- RpcIn_SetRetVals(result, resultLen,
- "Unable to start/stop time sync loop",
- retVal = FALSE);
- goto exit;
- }
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_SLEWCORRECTION) == 0) {
- data->slewCorrection = strcmp(value, "0");
- Debug("Daemon: Setting slewCorrection, %d.\n", data->slewCorrection);
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERCENTCORRECTION) == 0) {
- int32 percent;
- if (StrUtil_StrToInt(&percent, value)) {
- data->slewPercentCorrection = percent;
- }
- } else if (strcmp(option, TOOLSOPTION_BROADCASTIP) == 0 &&
- strcmp(value, "1") == 0) {
- char *ip;
-
- ip = NetUtil_GetPrimaryIP();
-
- if (ip == NULL) {
- RpcIn_SetRetVals(result, resultLen, "Error getting IP address of guest",
- retVal = FALSE);
- RpcOut_sendOne(NULL, NULL, "info-set guestinfo.ip %s",
- GUESTINFO_IP_UNKNOWN);
- goto exit;
- }
-
- RpcOut_sendOne(NULL, NULL, "info-set guestinfo.ip %s",
- ip[0] == '\0' ? GUESTINFO_IP_UNKNOWN : ip);
- free(ip);
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_PERIOD) == 0) {
- uint32 period = atoi(value);
-
- /*
- * If the sync loop is running and
- * the time sync period has changed,
- * restart the loop with the new period value.
- * If the sync loop is not running,
- * just remember the new sync period value.
- */
- if (period != data->timeSyncPeriod) {
- data->timeSyncPeriod = period * 100;
-
- if (data->timeSyncEvent != NULL) {
- Bool status;
-
- /* Stop the loop. */
- status = ToolsDaemonStartStopTimeSyncLoop(data, FALSE);
-
- /* Start the loop with the new period value. */
- status = ToolsDaemonStartStopTimeSyncLoop(data, TRUE);
-
- if (!status) {
- RpcIn_SetRetVals(result, resultLen,
- "Unable to change time sync period value",
- retVal = FALSE);
- goto exit;
- }
- }
- }
- } else if (strcmp(option, TOOLSOPTION_SYNCTIME_STARTUP) == 0) {
- uint32 syncStartupOk = atoi(value);
-
- if (timeSyncStartup) {
- timeSyncStartup = FALSE;
-
- if (syncStartupOk) {
- if (!ToolsDaemon_SyncTime(TRUE, TRUE, clientData)) {
- RpcIn_SetRetVals(result, resultLen,
- "Unable to sync time during startup",
- retVal = FALSE);
- goto exit;
- }
- }
- }
- } else if (strcmp(option, TOOLSOPTION_LINK_ROOT_HGFS_SHARE) == 0) {
- if (strcmp(value, "1") == 0) {
- /* Validated that data->linkHgfsCB existed above. */
- retVal = data->linkHgfsCB(data->linkHgfsCBData);
- } else if (strcmp(value, "0") == 0) {
- /* Validated that data->unlinkHgfsCB existed above. */
- retVal = data->unlinkHgfsCB(data->unlinkHgfsCBData);
- }
-
- if (!retVal) {
- RpcIn_SetRetVals(result, resultLen,
- "Could not link/unlink root share.",
- retVal = FALSE);
- goto exit;
- }
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWERON) == 0) {
- data->toolScriptOption[GUESTOS_STATECHANGE_POWERON] =
- strcmp(value, "0") ? TRUE : FALSE;
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_POWEROFF) == 0) {
- data->toolScriptOption[GUESTOS_STATECHANGE_HALT] =
- data->toolScriptOption[GUESTOS_STATECHANGE_REBOOT] =
- strcmp(value, "0") ? TRUE : FALSE;
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_SUSPEND) == 0) {
- data->toolScriptOption[GUESTOS_STATECHANGE_SUSPEND] =
- strcmp(value, "0") ? TRUE : FALSE;
- } else if (strcmp(option, TOOLSOPTION_SCRIPTS_RESUME) == 0) {
- data->toolScriptOption[GUESTOS_STATECHANGE_RESUME] =
- strcmp(value, "0") ? TRUE : FALSE;
- }
-
- /* success! */
- RpcIn_SetRetVals(result, resultLen, "", retVal = TRUE);
- goto exit;
-
- invalid_option:
- RpcIn_SetRetVals(result, resultLen, "Unknown option", retVal = FALSE);
- goto exit;
-
- invalid_value:
- RpcIn_SetRetVals(result, resultLen, "Invalid option value",
- retVal = FALSE);
- goto exit;
-
- exit:
- free(option);
- free(value);
- return retVal;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonTcloError --
- *
- * Callback called when an error occurred in the receive loop
- *
- * Return value:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-ToolsDaemonTcloError(void *clientData, // IN
- char const *status) // IN
-{
- ToolsDaemon_Data *data = (ToolsDaemon_Data *)clientData;
-
- ASSERT(data);
-
- Warning("Error in the RPC receive loop: %s.\n\n", status);
- data->inError = TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_Init_Backdoor --
- *
- * Initializes the backdoor to the VMX.
- *
- * Return value:
- * TRUE if successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-ToolsDaemon_Init_Backdoor(ToolsDaemon_Data * data) // IN/OUT
-{
- data->in = RpcIn_Construct(ToolsDaemonEventQueue);
- if (data->in == NULL) {
- Warning("Unable to create the RpcIn object.\n\n");
- return FALSE;
- }
-
- /*
- * Initialize 'inError' before starting the loop -- clients should
- * only read this flag.
- */
- data->inError = FALSE;
-
-
- /* Start the TCLO receive loop */
- if (RpcIn_start(data->in, RPCIN_POLL_TIME,
- ToolsDaemonTcloReset, data,
- ToolsDaemonTcloError, data) == FALSE) {
- RpcIn_Destruct(data->in);
- data->in = NULL;
- Warning("Unable to start the receive loop.\n\n");
- return FALSE;
- }
-
- RpcIn_RegisterCallback(data->in, "Time_Synchronize",
- ToolsDaemonTcloTimeSync, NULL);
- RpcIn_RegisterCallback(data->in, "Capabilities_Register",
- ToolsDaemonTcloCapReg, data);
- RpcIn_RegisterCallback(data->in, "Set_Option",
- ToolsDaemonTcloSetOption, data);
-
- /*
- * Bug 294328: Mac OS guests do not (yet) support the state change RPCs.
- */
-#ifndef __APPLE__
- {
- int i;
- for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) {
- RpcIn_RegisterCallback(data->in, stateChangeCmdTable[i].tcloCmd,
- ToolsDaemonTcloStateChange, data);
- }
- }
-#endif // ifndef __APPLE__
-
-#if !defined(N_PLAT_NLM)
- FoundryToolsDaemon_RegisterRoutines(data->in,
- data->pConfDict,
- ToolsDaemonEventQueue,
- TRUE);
- if (!HgfsServerManager_Register(data->in, TOOLS_DAEMON_NAME)) {
- RpcIn_stop(data->in);
- RpcIn_Destruct(data->in);
- data->in = NULL;
- Warning("Could not initialize HGFS server\n");
- return FALSE;
- }
-#endif
-
-#ifdef TOOLSDAEMON_HAS_RESOLUTION
- Resolution_InitBackdoor(data->in);
-#endif
-
-#if !defined(__FreeBSD__) && !defined(sun) && !defined(N_PLAT_NLM)
- DeployPkg_Register(data->in);
-#endif
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_Init --
- *
- * Setup a TCLO channel with VMware, and start it's event loop
- *
- * Return value:
- * the created RpcIn struct or
- * NULL if something failed (detail is displayed)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-ToolsDaemon_Data *
-ToolsDaemon_Init(GuestApp_Dict **pConfDict, // IN
- const char *execLogPath, // IN
- ToolsDaemon_Callback haltCB, // IN
- void *haltCBData, // IN
- ToolsDaemon_Callback rebootCB, // IN
- void *rebootCBData, // IN
- ToolsDaemon_Callback resetCB, // IN
- void *resetCBData, // IN
- ToolsDaemon_Callback linkHgfsCB, // IN
- void *linkHgfsCBData, // IN
- ToolsDaemon_Callback unlinkHgfsCB, // IN
- void *unlinkHgfsCBData) // IN
-{
- ToolsDaemon_Data *data;
- int i;
-
-#ifndef N_PLAT_NLM
- Atomic_Init();
-#endif // #ifndef N_PLAT_NLM
-
- ASSERT(pConfDict);
- ASSERT(*pConfDict);
- ASSERT(haltCB != NULL);
- ASSERT(rebootCB != NULL);
-
- data = (ToolsDaemon_Data *) calloc(1, sizeof(ToolsDaemon_Data));
- ASSERT_MEM_ALLOC(data);
-
- data->pConfDict = pConfDict;
- data->execLogPath = execLogPath;
- data->inError = FALSE;
- data->haltCB = haltCB;
- data->haltCBData = haltCBData;
- data->rebootCB = rebootCB;
- data->rebootCBData = rebootCBData;
- data->stateChgInProgress = GUESTOS_STATECHANGE_NONE;
- data->lastFailedStateChg = GUESTOS_STATECHANGE_NONE;
- data->resetCB = resetCB;
- data->resetCBData = resetCBData;
- data->linkHgfsCB = linkHgfsCB;
- data->linkHgfsCBData = linkHgfsCBData;
- data->unlinkHgfsCB = unlinkHgfsCB;
- data->unlinkHgfsCBData = unlinkHgfsCBData;
- data->timeSyncPeriod = 0;
- data->slewPercentCorrection = PERCENT_CORRECTION;
- data->slewCorrection = TRUE;
-
- for (i = 0; i < GUESTOS_STATECHANGE_LAST; i++) {
- data->toolScriptOption[i] = TRUE;
- }
-
-#if ALLOW_TOOLS_IN_FOREIGN_VM
- if (!VmCheck_IsVirtualWorld()) {
- ToolsDaemon_InitializeForeignVM(data);
- }
-#endif
-
-#if defined(VMX86_DEBUG) && !defined(__APPLE__)
- {
- /* Make sure the confDict has all the confs we need */
- for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) {
- const char *confName;
-
- confName = stateChgConfNames[stateChangeCmdTable[i].id];
- ASSERT(GuestApp_GetDictEntry(*pConfDict, confName));
- }
- }
-#endif
-
- ToolsDaemonEventQueue = EventManager_Init();
- if(!ToolsDaemonEventQueue) {
- Warning("Unable to create the event queue.\n\n");
- goto error;
- }
-
-#ifdef TOOLSDAEMON_HAS_RESOLUTION
- if (!Resolution_Init(TOOLS_DAEMON_NAME, NULL)) {
- Debug("%s: Unable to initialize Guest Fit feature\n", __func__);
- }
-#endif
-
- /*
- * Load the conf file, then setup a periodic check and reload.
- */
- Debug_Set(GuestApp_GetDictEntryBool(*pConfDict, CONFNAME_LOG), DEBUG_PREFIX);
-
- /*
- * All components except vmware-user will be logged to same file. Everytime after
- * reboot, tools daemon should rename existing log file and start logging to a new
- * one. In all other cases the backup flag for Debug_EnableToFile should be set to
- * FALSE.
- */
- Debug_EnableToFile(GuestApp_GetDictEntry(*pConfDict, CONFNAME_LOGFILE), TRUE);
-
- EventManager_Add(ToolsDaemonEventQueue, CONF_POLL_TIME, ToolsDaemonConfFileLoop,
- data->pConfDict);
-
- if (!ToolsDaemon_Init_Backdoor(data)) {
- goto error;
- }
-
- data->optionsDict = GuestApp_ConstructDict(NULL);
-
- return data;
-
- error:
- if (ToolsDaemonEventQueue) {
- EventManager_Destroy(ToolsDaemonEventQueue);
- ToolsDaemonEventQueue = NULL;
- }
- free(data);
- return NULL;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_Cleanup_Backdoor --
- *
- * Closes the backdoor to the VMX.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ToolsDaemon_Cleanup_Backdoor(ToolsDaemon_Data *data) // IN/OUT
-{
- ASSERT(data);
- if (data->in) {
-#if !defined(N_PLAT_NLM)
- HgfsServerManager_Unregister(data->in, TOOLS_DAEMON_NAME);
-#endif
- RpcIn_stop(data->in);
- RpcIn_Destruct(data->in);
- data->in = NULL;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_Cleanup --
- *
- * Cleanup the RpcIn channel if it hasn't been destructed yet& free the
- * local options.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ToolsDaemon_Cleanup(ToolsDaemon_Data *data) // IN
-{
-#ifdef _WIN32
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.resolution_set 0")) {
- Debug("%s: Unable to unregister resolution set capability\n",
- __FUNCTION__);
- }
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.resolution_server %s 0",
- TOOLS_DAEMON_NAME)) {
- Debug("%s: Unable to unregister resolution server capability\n",
- __FUNCTION__);
- }
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.display_topology_set 0")) {
- Debug("%s: Unable to unregister display topology set capability\n",
- __FUNCTION__);
- }
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.display_global_offset 0")) {
- Debug("%s: Unable to unregister display global offset capability\n",
- __FUNCTION__);
- }
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.color_depth_set 0")) {
- Debug("%s: Unable to unregister color depth set capability\n",
- __FUNCTION__);
- }
-
- /*
- * Clear the minimum resolution limitation.
- */
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.resolution_min 0 0")) {
- Debug("%s: Unable to clear minimum resolution\n", __FUNCTION__);
- }
-
- HgfsUsability_UnregisterServiceCaps();
-#endif
-
-#ifdef TOOLSDAEMON_HAS_RESOLUTION
- Resolution_Cleanup();
-#endif
-
-#if defined(_WIN32) || defined(linux)
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.auto_upgrade 0")) {
- Debug("%s: Unable to clear auto-upgrading capability.\n", __FUNCTION__);
- }
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.guest_temp_directory 0")) {
- Debug("%s: Unable to clear guest temp directory capability.\n",
- __FUNCTION__);
- }
-#endif
-
-#if !defined(N_PLAT_NLM)
- if (!RpcOut_sendOne(NULL, NULL, "tools.capability.guest_conf_directory 0")) {
- Debug("%s: Unable to clear guest conf directory capability.\n",
- __FUNCTION__);
- }
-#endif
-
-#if ALLOW_TOOLS_IN_FOREIGN_VM
- if (runningInForeignVM) {
- ToolsDaemon_ShutdownForeignVM();
- }
-#endif
-
- ToolsDaemon_Cleanup_Backdoor(data);
-
- GuestApp_FreeDict(data->optionsDict);
-
- if (data->asyncProc) {
- ProcMgr_Kill(data->asyncProc);
- ToolsDaemonStateChangeDone(FALSE, data);
- }
-
- EventManager_Destroy(ToolsDaemonEventQueue);
- free(data);
- free(guestTempDirectory);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_CheckReset --
- *
- * Can/should be called in an app's main run loop before calling the
- * 'sleep' function, to check and potentially reset the rpc layer.
- *
- * Return value:
- * TRUE if no errors were encountered, or rpc re-initialization is in
- * progress and we haven't exceeded the maximum number of consecutive
- * recovery attempts
- * FALSE rpc can't be re-initialized, or we exhausted our attempts quota
- *
- * Side effects:
- * Changes 'data'.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-ToolsDaemon_CheckReset(ToolsDaemon_Data *data, // IN/OUT
- uint64 *sleepUsecs) // IN/OUT
-{
- static int channelTimeoutAttempts = -1;
- char *tmp = NULL;
-
- ASSERT(data);
-
- if (channelTimeoutAttempts < 0) {
- Debug("Attempting to retrieve number of channel timeout attempts "
- "from vmx\n");
- /*
- * Currenly, we still use the 'guestinfo' alias. When the main branches
- * are synced up and the 'guestvars' code becomes stable, we'll move to
- * using the un-prefixed key.
- */
- if (RpcOut_sendOne(&tmp, NULL,
- "info-get guestinfo.guest_rpc.tclo.timeout") && tmp) {
- Debug("Retrieved channel timeout attempts from vmx: %s\n", tmp);
- channelTimeoutAttempts = atoi(tmp);
- }
- free(tmp);
- /* Safe-guard attempts against negative and too high-values. */
- if (channelTimeoutAttempts <= 0) {
- channelTimeoutAttempts = 60;
- Debug("Assuming %d channel timeout attempts\n",
- channelTimeoutAttempts);
- } else if (channelTimeoutAttempts > 180) {
- channelTimeoutAttempts = 180;
- Debug("Limiting to %d channel timeout attempts\n",
- channelTimeoutAttempts);
- }
- /*
- * Double it. This handles the case where the host is heavily loaded and
- * host (real) and guest (virtual) times diverge to the point where the
- * guest process timeouts before the VMX can reset the channel. This
- * makes the guest process wait sufficiently long. Note that since the
- * max above is 180 attempts, it is possible to wait 360 * sleepUsecs,
- * which by default is 360 seconds.
- */
- channelTimeoutAttempts *= 2;
- Debug("Backdoor resetting will be attemped at most %d times\n",
- channelTimeoutAttempts);
- }
-
- if (data->inError) {
- if (++(data->errorCount) > channelTimeoutAttempts) {
- Warning("Failed to reset backdoor after %d attempts\n",
- data->errorCount - 1);
- return FALSE;
- }
-
- Debug("Resetting backdoor [%d]\n", data->errorCount);
- if (RpcIn_restart(data->in) == FALSE) {
- Warning("Backdoor reset failed [%d]\n", data->errorCount);
- return FALSE;
- }
- data->inError = FALSE;
-
- *sleepUsecs = (uint64)1000000;
- } else {
- if ( *sleepUsecs > 0 && data->errorCount > 0) {
- Debug("Backdoor was reset successfully\n");
- data->errorCount = 0;
- }
- }
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_SetOsPhase --
- *
- * Set the guest OS phase in the VMX
- *
- * Return value:
- * TRUE on success
- * FALSE on failure
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-ToolsDaemon_SetOsPhase(Bool stateChangeSucceeded, // IN
- unsigned int cmdId) // IN
-{
- return RpcOut_sendOne(NULL, NULL, "tools.os.statechange.status %d %d",
- stateChangeSucceeded, cmdId);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_GetMinResolution --
- *
- * Get the minimum resolution (height and width) that we support
- * setting this guest to.
- *
- * This was originally added for bug 58681.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ToolsDaemon_GetMinResolution(GuestApp_Dict *dict, // IN
- unsigned int *width, // OUT
- unsigned int *height) // OUT
-{
- ASSERT(width);
- ASSERT(height);
-
- /*
- * This code is no longer used for Win9x platforms, and it's assumed that
- * all other platforms don't have a minimum.
- */
- *width = 0;
- *height = 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_GetGuestTempDirectory --
- *
- * Return the guest temp directory.
- *
- * Results:
- * The guest temp directory
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-const char *
-ToolsDaemon_GetGuestTempDirectory(void)
-{
- return guestTempDirectory;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_InitializeForeignVM --
- *
- * This is called when the tools are not running in a VM in VMware.
- * Register appropriate backdoor procedures, and open the foreign tools
- * listener socket.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ToolsDaemon_InitializeForeignVM(ToolsDaemon_Data *toolsDaemonData) // IN
-{
- Bool success;
-
- runningInForeignVM = TRUE;
-
- MessageStub_RegisterTransport();
-
- success = ForeignTools_Initialize(toolsDaemonData->optionsDict);
-} // ToolsDaemon_InitializeForeignVM
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemon_ShutdownForeignVM --
- *
- * This is called when the tools are not running in a VM in VMware.
- * Close the foreign tools listener socket.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ToolsDaemon_ShutdownForeignVM(void)
-{
- ForeignTools_Shutdown();
-} // ToolsDaemon_ShutdownForeignVM
-
-
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2001 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-
-/*
- * toolsDaemon.h --
- *
- * Platform independent methods used by the tools daemon/win32-service.
- *
- */
-
-
-#ifndef __TOOLSDAEMON_H__
-# define __TOOLSDAEMON_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vm_basic_types.h"
-#include "vm_app.h"
-#include "guestApp.h"
-#include "procMgr.h"
-#include "dbllnklst.h"
-#include "file.h"
-
-typedef Bool ToolsDaemon_Callback(void *clientData);
-
-#ifndef DEBUG_PREFIX
-#define DEBUG_PREFIX "vmsvc"
-#endif
-
-/*
- * ToolsDaemon "member" data.
- */
-typedef struct ToolsDaemon_Data {
- struct RpcIn *in;
- const char *execLogPath;
- Bool inError;
- int errorCount;
- GuestApp_Dict *optionsDict; // the options we get from VMware
- GuestApp_Dict **pConfDict; // the name/value pairs from the conf file
- struct Event *timeSyncEvent;
- uint32 timeSyncPeriod;
- uint32 slewPercentCorrection;
- Bool slewCorrection;
- struct Event *oldOptionsLoop;
- ToolsDaemon_Callback *haltCB; // callback when we do a soft halt
- void *haltCBData; // its data
- ToolsDaemon_Callback *rebootCB; // callback when we do a soft reboot
- void *rebootCBData; // its data
- ToolsDaemon_Callback *resetCB; // callback when we receive a reset
- void *resetCBData; // its data
- ToolsDaemon_Callback *linkHgfsCB; // callback to create hgfs link on desktop
- void *linkHgfsCBData; // its data
- ToolsDaemon_Callback *unlinkHgfsCB; // callback to remove hgfs link on desktop
- void *unlinkHgfsCBData; // its data
- GuestOsState stateChgInProgress;
- GuestOsState lastFailedStateChg;
- ProcMgr_AsyncProc *asyncProc;
- ProcMgr_Callback *asyncProcCb;
- void *asyncProcCbData;
- Bool toolScriptOption[GUESTOS_STATECHANGE_LAST]; // toolsScript option from vmx
-} ToolsDaemon_Data;
-
-
-ToolsDaemon_Data *
-ToolsDaemon_Init(GuestApp_Dict **pConfDict, // IN
- const char *execLogPath, // IN
- ToolsDaemon_Callback haltCB, // IN
- void *haltCBData, // IN
- ToolsDaemon_Callback rebootCB, // IN
- void *rebootCBData, // IN
- ToolsDaemon_Callback resetCB, // IN
- void *resetCBData, // IN
- ToolsDaemon_Callback linkHgfsCB, // IN
- void *linkHgfsCBData, // IN
- ToolsDaemon_Callback unlinkHgfsCB, // IN
- void *unlinkHgfsCBData); // IN
-
-Bool
-ToolsDaemon_Init_Backdoor(ToolsDaemon_Data *data); // IN/OUT
-
-void
-ToolsDaemon_Cleanup(ToolsDaemon_Data *data); // IN/OUT
-
-Bool
-ToolsDaemon_CheckReset(ToolsDaemon_Data *data, // IN/OUT
- uint64 *sleepUsecs); // IN/OUT
-
-void
-ToolsDaemon_Cleanup_Backdoor(ToolsDaemon_Data *data); // IN/OUT
-
-Bool
-ToolsDaemon_SyncTime(Bool syncBackward, // IN
- Bool syncOnce, // IN
- void *toolsDaemonData); // IN
-
-Bool
-ToolsDaemon_SetOsPhase(Bool stateChangeSucceeded,
- unsigned int cmdId);
-
-void
-ToolsDaemon_GetMinResolution(GuestApp_Dict *dict, // IN
- unsigned int *width, // OUT
- unsigned int *height); // OUT
-
-const char *
-ToolsDaemon_GetGuestTempDirectory(void);
-
-#if !defined(N_PLAT_NLM) && !defined(sun)
-Bool
-ToolsDaemonHgfs(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- unsigned int argsSize, // IN: Size of args
- void *clientData); // Unused
-#endif
-
-Bool
-ForeignTools_Initialize(GuestApp_Dict *configDictionaryParam);
-
-void
-ForeignTools_Shutdown(void);
-
-
-/* Queue of timer events for the tools daemon. */
-extern DblLnkLst_Links *ToolsDaemonEventQueue;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TOOLSDAEMON_H__ */
endif
SUBDIRS += user
SUBDIRS += vixTools
-SUBDIRS += vmBackupLib
SUBDIRS += vmCheck
SUBDIRS += vmSignal
SUBDIRS += wiper
// don't free path; it's used by the dict
/* Set default conf values */
-#if !defined(_WIN32) && !defined(N_PLAT_NLM)
- GuestApp_SetDictEntryDefault(confDict, CONFNAME_HALT, CONFVAL_HALT_DEFAULT);
- GuestApp_SetDictEntryDefault(confDict, CONFNAME_REBOOT, CONFVAL_REBOOT_DEFAULT);
- GuestApp_SetDictEntryDefault(confDict, CONFNAME_MOUNT_POINT,
- CONFVAL_MOUNT_POINT_DEFAULT);
-#endif
-
path = Str_Asprintf(NULL, "%s%c%s", installPath, DIRSEPC,
CONFVAL_POWERONSCRIPT_DEFAULT);
ASSERT_NOT_IMPLEMENTED(path);
/*
- * toolsDeployPkg.h
+ * toolsDeployPkg.h
*
- * -- Define constants & exported methods related to tools package deployment.
+ * -- Define constants related to tools package deployment.
*/
typedef enum {
TOOLSDEPLOYPKG_ERROR_DEPLOY_FAILED,
} ToolsDeployPkgError;
-Bool ToolsDeployPkg_PowerOn(void);
-void ToolsDeployPkg_Begin(void);
-
#endif //__TOOLS_DEPLOYPKG_H_
return FALSE;
}
+ if (size >= CPCLIPITEM_MAX_SIZE_V3) {
+ return FALSE;
+ }
+
+ if (CPFORMAT_RTF == fmt) {
+ size_t textSize = clip->items[CPFormatToIndex(CPFORMAT_TEXT)].size;
+ if ((textSize + size) >= CPCLIPITEM_MAX_SIZE_V3) {
+ /*
+ * If both CPFORMAT_TEXT and CPFORMAT_RTF are availabe but total
+ * size is over limit, only keep CPFORMAT_TEXT.
+ */
+ return TRUE;
+ }
+ }
+
+ if (CPFORMAT_TEXT == fmt) {
+ size_t rtfSize = clip->items[CPFormatToIndex(CPFORMAT_RTF)].size;
+ if ((rtfSize + size) >= CPCLIPITEM_MAX_SIZE_V3) {
+ /*
+ * If both CPFORMAT_TEXT and CPFORMAT_RTF are availabe but total
+ * size is over limit, remove data for CPFORMAT_RTF and add data
+ * for CPFORMAT_TEXT.
+ */
+ if (!CPClipboard_ClearItem(clip, CPFORMAT_RTF)) {
+ return FALSE;
+ }
+ }
+ }
+
item = &clip->items[CPFormatToIndex(fmt)];
if (clipitem) {
*/
unescapedName = Escape_Undo('%', file, fileLength, &unescapedLength);
if (!unescapedName) {
- Warning("DnD_UriListGetNextFile: error unescaping filename\n");
+ Warning("%s: error unescaping filename\n", __func__);
return NULL;
}
/* We need to make this suck less. */
#if defined(linux) || defined(sun) || defined(__FreeBSD__)
+
+#if defined(linux)
+
+static INLINE int
+VMBLOCK_CONTROL(int fd, int op, const char *path)
+{
+ return write(fd, path, op);
+}
+
+#elif defined(__FreeBSD__)
+
+static INLINE int
+VMBLOCK_CONTROL(int fd, int cmd, const char *path)
+{
+ char tpath[MAXPATHLEN];
+
+ if (path != NULL) {
+ /*
+ * FreeBSD's ioctl data parameters must be of fixed size. Guarantee a safe
+ * buffer of size MAXPATHLEN by copying the user's string to one of our own.
+ */
+ strlcpy(tpath, path, MAXPATHLEN);
+ }
+
+ return ioctl(fd, cmd, tpath);
+}
+
+#elif defined(sun)
+
+static INLINE int
+VMBLOCK_CONTROL(int fd, int cmd, const char *path)
+{
+ return ioctl(fd, cmd, path);
+}
+
+#endif
+
+
/*
*----------------------------------------------------------------------------
*
- * DnD_InitializeBlocking --
+ * DnD_AddBlockLegacy --
+ *
+ * Adds a block to blockPath.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * Processes trying to access this path will block until DnD_RemoveBlock
+ * is called.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+DnD_AddBlockLegacy(int blockFd, // IN
+ const char *blockPath) // IN
+{
+ ASSERT(blockFd >= 0);
+
+ if (VMBLOCK_CONTROL(blockFd, VMBLOCK_ADD_FILEBLOCK, blockPath) != 0) {
+ LOG(1, ("%s: Cannot add block on %s (%s)\n",
+ __func__, blockPath, strerror(errno)));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * DnD_RemoveBlockLegacy --
+ *
+ * Removes block on blockedPath.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * Processes blocked on accessing this path will continue.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+DnD_RemoveBlockLegacy(int blockFd, // IN
+ const char *blockedPath) // IN
+{
+ if (blockFd >= 0) {
+ if (VMBLOCK_CONTROL(blockFd, VMBLOCK_DEL_FILEBLOCK, blockedPath) != 0) {
+ Log("%s: Cannot delete block on %s (%s)\n",
+ __func__, blockedPath, strerror(errno));
+ return FALSE;
+ }
+ } else {
+ LOG(4, ("%s: Could not remove block on %s: "
+ "fd to vmblock no longer exists.\n", __func__, blockedPath));
+ }
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * DnD_CheckBlockLegacy --
+ *
+ * Verifies that given file descriptor is truly a control file of
+ * kernel-based vmblock implementation. Just a stub, for now at
+ * least since we don't have a good way to check.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static Bool
+DnD_CheckBlockLegacy(int blockFd) // IN
+{
+ return TRUE;
+}
+
+
+/*
+ * DnD_VmblockFuseControl --
+ *
+ * Controlling function for FUSE-based blocker implementation.
+ * Passes requests to block and unblock file access to fuse module.
+ *
+ * Results:
+ * 0 on success, -1 on failure.
+ *
+ * Notes:
+ * None.
+ *
+ */
+
+static ssize_t
+DnD_VmblockFuseControl(int fd, // IN
+ char op, // IN
+ const char *path) // IN
+{
+ /*
+ * buffer needs room for an operation character and a string with max length
+ * PATH_MAX - 1.
+ */
+
+ char buffer[PATH_MAX];
+ size_t pathLength;
+
+ pathLength = strlen(path);
+ if (pathLength >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ buffer[0] = op;
+ memcpy(buffer + 1, path, pathLength);
+
+ /*
+ * The lseek is only to prevent the file pointer from overflowing;
+ * vmblock-fuse ignores the file pointer / offset. Overflowing the file
+ * pointer causes write to fail:
+ * http://article.gmane.org/gmane.comp.file-systems.fuse.devel/6648
+ * There's also a race condition here where many threads all calling
+ * VMBLOCK_CONTROL at the same time could have all their seeks executed one
+ * after the other, followed by all the writes. Again, it's not a problem
+ * unless the file pointer overflows which is very unlikely with 32 bit
+ * offsets and practically impossible with 64 bit offsets.
+ */
+
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ return -1;
+ }
+
+ if (write(fd, buffer, pathLength + 1) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * DnD_AddBlockFuse --
+ *
+ * Adds a block to blockPath.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * Processes trying to access this path will block until DnD_RemoveBlock
+ * is called.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+DnD_AddBlockFuse(int blockFd, // IN
+ const char *blockPath) // IN
+{
+ ASSERT(blockFd >= 0);
+
+ if (DnD_VmblockFuseControl(blockFd, VMBLOCK_FUSE_ADD_FILEBLOCK,
+ blockPath) != 0) {
+ LOG(1, ("%s: Cannot add block on %s (%s)\n",
+ __func__, blockPath, strerror(errno)));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * DnD_RemoveBlockFuse --
+ *
+ * Removes block on blockedPath.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * Processes blocked on accessing this path will continue.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+DnD_RemoveBlockFuse(int blockFd, // IN
+ const char *blockedPath) // IN
+{
+ if (blockFd >= 0) {
+ if (DnD_VmblockFuseControl(blockFd, VMBLOCK_FUSE_DEL_FILEBLOCK,
+ blockedPath) != 0) {
+ Log("%s: Cannot delete block on %s (%s)\n",
+ __func__, blockedPath, strerror(errno));
+ return FALSE;
+ }
+ } else {
+ LOG(4, ("%s: Could not remove block on %s: "
+ "fd to vmblock no longer exists.\n", __func__, blockedPath));
+ }
+
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * DnD_CheckBlockFuse --
+ *
+ * Verifies that given file descriptor is truly a control file of
+ * FUSE-based vmblock implementation.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static Bool
+DnD_CheckBlockFuse(int blockFd) // IN
+{
+ char buf[sizeof(VMBLOCK_FUSE_READ_RESPONSE)];
+ size_t size;
+
+ size = read(blockFd, buf, sizeof(VMBLOCK_FUSE_READ_RESPONSE));
+ if (size < 0) {
+ LOG(4, ("%s: read failed, error %s.\n",
+ __func__, strerror(errno)));
+ return FALSE;
+ }
+
+ if (size != sizeof(VMBLOCK_FUSE_READ_RESPONSE)) {
+ LOG(4, ("%s: Response too short (%"FMTSZ"d vs. %"FMTSZ"u).\n",
+ __func__, size, sizeof(VMBLOCK_FUSE_READ_RESPONSE)));
+ return FALSE;
+ }
+
+ if (memcmp(buf, VMBLOCK_FUSE_READ_RESPONSE,
+ sizeof(VMBLOCK_FUSE_READ_RESPONSE))) {
+ LOG(4, ("%s: Invalid response %.*s",
+ __func__, (int)sizeof(VMBLOCK_FUSE_READ_RESPONSE) - 1, buf));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * DnD_TryInitVmblock --
*
* Initializes file blocking needed to prevent access to file before
* transfer has finished.
*----------------------------------------------------------------------------
*/
-int
-DnD_InitializeBlocking(void)
+static int
+DnD_TryInitVmblock(const char *vmbFsName, // IN
+ const char *vmbMntPoint, // IN
+ const char *vmbDevice, // IN
+ mode_t vmbDeviceMode, // IN
+ Bool (*verifyBlock)(int fd)) // IN
{
- uid_t uid;
Bool found = FALSE;
int blockFd = -1;
MNTHANDLE fp;
DECLARE_MNTINFO(mnt);
- /* root access is needed for opening the vmblock device */
- uid = Id_BeginSuperUser();
-
/* Make sure the vmblock file system is mounted. */
fp = OPEN_MNTFILE("r");
if (fp == NULL) {
- LOG(1, ("DnD_InitializeBlocking: could not open mount file\n"));
- (void) CLOSE_MNTFILE(fp);
- goto out;
+ LOG(1, ("%s: could not open mount file\n", __func__));
+ return -1;
}
while (GETNEXT_MNTINFO(fp, mnt)) {
* In the future we can publish the mount point in VMDB so that the UI
* can use it rather than enforcing the VMBLOCK_MOUNT_POINT check here.
*/
- if (strcmp(MNTINFO_FSTYPE(mnt), VMBLOCK_FS_NAME) == 0 &&
- strcmp(MNTINFO_MNTPT(mnt), VMBLOCK_MOUNT_POINT) == 0) {
+ if (strcmp(MNTINFO_FSTYPE(mnt), vmbFsName) == 0 &&
+ strcmp(MNTINFO_MNTPT(mnt), vmbMntPoint) == 0) {
found = TRUE;
break;
}
(void) CLOSE_MNTFILE(fp);
- if (!found) {
- LOG(4, ("DnD_InitializeBlocking: could not find vmblock mounted\n"));
- goto out;
- }
-
- /* Open device node for communication with vmblock. */
- blockFd = Posix_Open(VMBLOCK_DEVICE, VMBLOCK_DEVICE_MODE);
- if (blockFd < 0) {
- LOG(1, ("DnD_InitializeBlocking: Can not open blocker device (%s)\n",
- strerror(errno)));
- goto out;
+ if (found) {
+ /* Open device node for communication with vmblock. */
+ blockFd = Posix_Open(vmbDevice, vmbDeviceMode);
+ if (blockFd < 0) {
+ LOG(1, ("%s: Can not open blocker device (%s)\n",
+ __func__, strerror(errno)));
+ } else {
+ LOG(4, ("%s: Opened blocker device at %s\n",
+ __func__, VMBLOCK_DEVICE));
+ if (verifyBlock && !verifyBlock(blockFd)) {
+ LOG(4, ("%s: Blocker device at %s did not pass checks, closing.\n",
+ __func__, VMBLOCK_DEVICE));
+ close(blockFd);
+ blockFd = -1;
+ }
+ }
}
- LOG(4, ("DnD_InitializeBlocking: Opened blocker device at %s\n",
- VMBLOCK_DEVICE));
-
-out:
- Id_EndSuperUser(uid);
return blockFd;
}
/*
*----------------------------------------------------------------------------
*
- * DnD_UninitializeBlocking --
+ * DnD_InitializeBlocking --
*
- * Uninitialize file blocking.
+ * Initializes file blocking needed to prevent access to file before
+ * transfer has finished.
*
* Results:
* TRUE on success, FALSE on failure.
*
* Side effects:
- * All existing blocks will be removed.
+ * None.
*
*----------------------------------------------------------------------------
*/
Bool
-DnD_UninitializeBlocking(int blockFd) // IN
+DnD_InitializeBlocking(DnDBlockControl *blkCtrl) // OUT
{
- Bool ret = TRUE;
- if (blockFd >= 0) {
- if (close(blockFd) < 0) {
- Log("DnD_UninitializeBlocking: Can not close blocker device (%s)\n",
- strerror(errno));
- ret = FALSE;
- }
+ uid_t uid;
+ int blockFd;
+
+ /* Root access is needed for opening the vmblock device. */
+ uid = Id_BeginSuperUser();
+
+ /* Fitrst try FUSE and see if it is available. */
+ blockFd = DnD_TryInitVmblock(VMBLOCK_FUSE_FS_NAME, VMBLOCK_FUSE_MOUNT_POINT,
+ VMBLOCK_FUSE_DEVICE, VMBLOCK_FUSE_DEVICE_MODE,
+ DnD_CheckBlockFuse);
+ if (blockFd != -1) {
+ blkCtrl->fd = blockFd;
+ /* Setup FUSE methods. */
+ blkCtrl->blockRoot = VMBLOCK_FUSE_FS_ROOT;
+ blkCtrl->AddBlock = DnD_AddBlockFuse;
+ blkCtrl->RemoveBlock = DnD_RemoveBlockFuse;
+ goto out;
}
- return ret;
+ /* Now try OS-specific VMBlock driver. */
+ blockFd = DnD_TryInitVmblock(VMBLOCK_FS_NAME, VMBLOCK_MOUNT_POINT,
+ VMBLOCK_DEVICE, VMBLOCK_DEVICE_MODE,
+ NULL);
+ if (blockFd != -1) {
+ blkCtrl->fd = blockFd;
+ /* Setup legacy in-kernel methods. */
+ blkCtrl->blockRoot = VMBLOCK_FS_ROOT;
+ blkCtrl->AddBlock = DnD_AddBlockLegacy;
+ blkCtrl->RemoveBlock = DnD_RemoveBlockLegacy;
+ goto out;
+ }
+
+ LOG(4, ("%s: could not find vmblock mounted\n", __func__));
+out:
+ Id_EndSuperUser(uid);
+
+ return blockFd != -1;
}
/*
*----------------------------------------------------------------------------
*
- * DnD_AddBlock --
+ * DnD_UninitializeBlocking --
*
- * Adds a block to blockPath.
+ * Uninitialize file blocking.
*
* Results:
* TRUE on success, FALSE on failure.
*
* Side effects:
- * Processes trying to access this path will block until DnD_RemoveBlock
- * is called.
+ * All existing blocks will be removed.
*
*----------------------------------------------------------------------------
*/
Bool
-DnD_AddBlock(int blockFd, // IN
- const char *blockPath) // IN
+DnD_UninitializeBlocking(DnDBlockControl *blkCtrl) // IN
{
- ASSERT(blockFd >= 0);
+ Bool ret = TRUE;
- if (VMBLOCK_CONTROL(blockFd, VMBLOCK_ADD_FILEBLOCK, blockPath) != 0) {
- LOG(1, ("DnD_AddBlock: Cannot add block on %s (%s)\n",
- blockPath, strerror(errno)));
- return FALSE;
+ if (blkCtrl->fd >= 0) {
+ if (close(blkCtrl->fd) < 0) {
+ Log("%s: Can not close blocker device (%s)\n",
+ __func__, strerror(errno));
+ ret = FALSE;
+ } else {
+ blkCtrl->fd = -1;
+ }
}
- return TRUE;
-}
+ return ret;
+}
/*
- *----------------------------------------------------------------------------
+ * DnD_CompleteBlockInitialization --
*
- * DnD_RemoveBlock --
- *
- * Removes block on blockedPath.
+ * Complete block initialization in case when we were handed
+ * blocking file descriptor (presumably opened for us by a
+ * suid application).
*
* Results:
- * TRUE on success, FALSE on failure.
+ * TRUE on success, FALSE on failure (invalid type).
*
* Side effects:
- * Processes blocked on accessing this path will continue.
+ * Adjusts blkCtrl to match blocking device type (legacy or fuse).
*
- *----------------------------------------------------------------------------
*/
Bool
-DnD_RemoveBlock(int blockFd, // IN
- const char *blockedPath) // IN
+DnD_CompleteBlockInitialization(int fd, // IN
+ DnDBlockControl *blkCtrl) // OUT
{
- if (blockFd >= 0) {
- if (VMBLOCK_CONTROL(blockFd, VMBLOCK_DEL_FILEBLOCK, blockedPath) != 0) {
- Log("DnD_RemoveBlock: Cannot delete block on %s (%s)\n",
- blockedPath, strerror(errno));
- return FALSE;
- }
+ blkCtrl->fd = fd;
+
+ if (DnD_CheckBlockFuse(fd)) {
+ /* Setup FUSE methods. */
+ blkCtrl->blockRoot = VMBLOCK_FUSE_FS_ROOT;
+ blkCtrl->AddBlock = DnD_AddBlockFuse;
+ blkCtrl->RemoveBlock = DnD_RemoveBlockFuse;
+ } else if (DnD_CheckBlockLegacy(fd)) {
+ /* Setup legacy methods. */
+ blkCtrl->blockRoot = VMBLOCK_FS_ROOT;
+ blkCtrl->AddBlock = DnD_AddBlockLegacy;
+ blkCtrl->RemoveBlock = DnD_RemoveBlockLegacy;
} else {
- LOG(4, ("DnD_RemoveBlock: Could not remove block on %s: fd to vmblock no "
- "longer exists.\n", blockedPath));
+ Log("%s: Can't determine block type.\n", __func__);
+ return FALSE;
}
+
return TRUE;
}
+
#endif /* linux || sun || FreeBSD */
libDndGuest_la_SOURCES += copyPasteRpcV3.cc
libDndGuest_la_SOURCES += dnd.cc
libDndGuest_la_SOURCES += dndFileList.cc
+libDndGuest_la_SOURCES += dndRpcV3.cc
libDndGuest_la_SOURCES += dndTransportGuestRpc.cc
return;
}
- mRpc->HGDropDone(cpName, cpNameSize);
sourceDropChanged.emit();
+ mRpc->HGDropDone(cpName, cpNameSize);
} else {
/* For non-file formats, the DnD is done. Hide detection window. */
updateDetWndChanged.emit(false, 0, 0);
{
OnHGCancel();
OnGHCancel();
+ reset.emit();
}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * DnDRpcV3.cc --
+ *
+ * Implementation of the DnDRpcV3 interface.
+ */
+
+
+#include "dndRpcV3.hh"
+#include "dndTransportGuestRpc.hh"
+
+extern "C" {
+ #include "dndMsg.h"
+ #include "debug.h"
+ #include "dndClipboard.h"
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DnDRpcV3 --
+ *
+ * Constructor of DnDRpcV3 class.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+DnDRpcV3::DnDRpcV3(struct RpcIn *rpcIn) // IN
+{
+ mTransport = new DnDTransportGuestRpc(rpcIn, "dnd.transport");
+ mTransport->recvMsgChanged.connect(sigc::mem_fun(this, &DnDRpcV3::OnRecvMsg));
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::~DnDRpcV3 --
+ *
+ * Destructor of DnDRpcV3.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+DnDRpcV3::~DnDRpcV3(void)
+{
+ delete mTransport;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::HGDragEnterDone --
+ *
+ * Serialize DND_HG_DRAG_ENTER_DONE message and forward to
+ * transport layer.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::HGDragEnterDone(int32 x, // IN
+ int32 y) // IN
+{
+ DnDMsg msg;
+ DynBuf buf;
+ bool ret = false;
+
+ DnDMsg_Init(&msg);
+ DynBuf_Init(&buf);
+
+ DnDMsg_SetCmd(&msg, DND_HG_DRAG_ENTER_DONE);
+
+ if (!DnDMsg_AppendArg(&msg, &x, sizeof x) ||
+ !DnDMsg_AppendArg(&msg, &y, sizeof y)) {
+ Debug("%s: DnDMsg_AppendData failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ if (!DnDMsg_Serialize(&msg, &buf)) {
+ Debug("%s: DnDMsg_Serialize failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ ret = mTransport->SendMsg((uint8 *)DynBuf_Get(&buf), DynBuf_GetSize(&buf));
+
+exit:
+ DynBuf_Destroy(&buf);
+ DnDMsg_Destroy(&msg);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::HGDragStartDone --
+ *
+ * Serialize DND_HG_DRAG_READY message and forward to
+ * transport layer.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::HGDragStartDone(void)
+{
+ return SendSingleCmd(DND_HG_DRAG_READY);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::HGUpdateFeedback --
+ *
+ * Serialize DND_HG_UPDATE_FEEDBACK message and forward to
+ * transport layer.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::HGUpdateFeedback(DND_DROPEFFECT effect) // IN
+{
+ DnDMsg msg;
+ DynBuf buf;
+ bool ret = false;
+
+ DnDMsg_Init(&msg);
+ DynBuf_Init(&buf);
+
+ DnDMsg_SetCmd(&msg, DND_HG_UPDATE_FEEDBACK);
+
+ if (!DnDMsg_AppendArg(&msg, &effect, sizeof effect)) {
+ Debug("%s: DnDMsg_AppendData failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ if (!DnDMsg_Serialize(&msg, &buf)) {
+ Debug("%s: DnDMsg_Serialize failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ ret = mTransport->SendMsg((uint8 *)DynBuf_Get(&buf), DynBuf_GetSize(&buf));
+
+exit:
+ DynBuf_Destroy(&buf);
+ DnDMsg_Destroy(&msg);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::HGDropDone --
+ *
+ * Serialize DND_HG_DROP_DONE message and forward to
+ * transport layer.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::HGDropDone(const char *stagingDirCP, // IN
+ size_t sz) // IN
+{
+ DnDMsg msg;
+ DynBuf buf;
+ bool ret = FALSE;
+
+ DnDMsg_Init(&msg);
+ DynBuf_Init(&buf);
+
+ /* Construct msg with both cmd CP_HG_START_FILE_COPY and stagingDirCP. */
+ DnDMsg_SetCmd(&msg, DND_HG_DROP_DONE);
+ if (!DnDMsg_AppendArg(&msg, (void *)stagingDirCP, sz)) {
+ Debug("%s: DnDMsg_AppendData failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /* Serialize msg and output to buf. */
+ if (!DnDMsg_Serialize(&msg, &buf)) {
+ Debug("%s: DnDMsg_Serialize failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ ret = mTransport->SendMsg((uint8 *)DynBuf_Get(&buf), DynBuf_GetSize(&buf));
+
+exit:
+ DynBuf_Destroy(&buf);
+ DnDMsg_Destroy(&msg);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::GHDragEnter --
+ *
+ * Serialize all parameters and pass to transport layer for
+ * DND_GH_DRAG_ENTER signal.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::GHDragEnter(const CPClipboard *clip) // IN
+{
+ return SendCmdWithClip(DND_GH_DRAG_ENTER, clip);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::GHUngrabTimeout --
+ *
+ * Serialize DND_GH_NOT_PENDING message and forward to
+ * transport layer.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::GHUngrabTimeout(void)
+{
+ return SendSingleCmd(DND_GH_NOT_PENDING);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::SendSingleCmd --
+ *
+ * Serialize message without any argument and forward to
+ * transport layer.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::SendSingleCmd(DnDCommand cmd) // IN
+{
+ DnDMsg msg;
+ DynBuf buf;
+ bool ret = false;
+
+ DnDMsg_Init(&msg);
+ DynBuf_Init(&buf);
+
+ DnDMsg_SetCmd(&msg, cmd);
+
+ if (!DnDMsg_Serialize(&msg, &buf)) {
+ Debug("%s: DnDMsg_Serialize failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ ret = mTransport->SendMsg((uint8 *)DynBuf_Get(&buf), DynBuf_GetSize(&buf));
+
+exit:
+ DynBuf_Destroy(&buf);
+ DnDMsg_Destroy(&msg);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * cui::dnd::DnDRpcV3::SendCmdWithClip --
+ *
+ * Serialize message with only clip data and forward to
+ * transport layer.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool
+DnDRpcV3::SendCmdWithClip(DnDCommand cmd, // IN
+ const CPClipboard *clip) // IN
+{
+ DnDMsg msg;
+ DynBuf buf;
+ bool ret = false;
+
+ DnDMsg_Init(&msg);
+ DynBuf_Init(&buf);
+
+ /* Serialize clip and output into buf. */
+ if (!CPClipboard_Serialize(clip, &buf)) {
+ Debug("%s: CPClipboard_Serialize failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /* Construct msg with both cmd CP_HG_SET_CLIPBOARD and buf. */
+ DnDMsg_SetCmd(&msg, cmd);
+ if (!DnDMsg_AppendArg(&msg, DynBuf_Get(&buf), DynBuf_GetSize(&buf))) {
+ Debug("%s: DnDMsg_AppendData failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /* Reset buf. */
+ DynBuf_Destroy(&buf);
+ DynBuf_Init(&buf);
+
+ /* Serialize msg and output to buf. */
+ if (!DnDMsg_Serialize(&msg, &buf)) {
+ Debug("%s: DnDMsg_Serialize failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ ret = mTransport->SendMsg((uint8 *)DynBuf_Get(&buf), DynBuf_GetSize(&buf));
+
+exit:
+ DynBuf_Destroy(&buf);
+ DnDMsg_Destroy(&msg);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DnDRpcV3::OnRecvMsg --
+ *
+ * Received a new message from transport layer. Unserialize and
+ * translate it and emit corresponding signal.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DnDRpcV3::OnRecvMsg(const uint8 *data, // IN
+ size_t dataSize) // IN
+{
+ DnDMsg msg;
+ DnDMsgErr ret;
+ DynBuf *buf = NULL;
+
+ DnDMsg_Init(&msg);
+
+ ret = DnDMsg_UnserializeHeader(&msg, (void *)data, dataSize);
+ if (DNDMSG_SUCCESS != ret) {
+ Debug("%s: DnDMsg_UnserializeHeader failed with %d\n",
+ __FUNCTION__, ret);
+ goto exit;
+ }
+
+ ret = DnDMsg_UnserializeArgs(&msg,
+ (void *)&data[DNDMSG_HEADERSIZE_V3],
+ dataSize - DNDMSG_HEADERSIZE_V3);
+ if (DNDMSG_SUCCESS != ret) {
+ Debug("%s: DnDMsg_UnserializeArgs failed with %d\n",
+ __FUNCTION__, ret);
+ goto exit;
+ }
+
+ /* Translate command and emit signal. */
+ switch (DnDMsg_GetCmd(&msg)) {
+ case DND_GH_UPDATE_UNITY_DET_WND:
+ {
+ bool bShow = false;
+ uint32 unityWndId;
+
+ buf = DnDMsg_GetArg(&msg, 0);
+ if (DynBuf_GetSize(buf) == sizeof(bool)) {
+ memcpy(&bShow, (const char *)DynBuf_Get(buf), sizeof(bool));
+ } else {
+ break;
+ }
+
+ buf = DnDMsg_GetArg(&msg, 1);
+ if (DynBuf_GetSize(buf) == sizeof(uint32)) {
+ memcpy(&unityWndId, (const char *)DynBuf_Get(buf), sizeof(uint32));
+ } else {
+ break;
+ }
+ ghUpdateUnityDetWndChanged.emit(bShow, unityWndId);
+
+ break;
+ }
+ case DND_GH_QUERY_PENDING_DRAG:
+ {
+ int32 x = 0;
+ int32 y = 0;
+
+ buf = DnDMsg_GetArg(&msg, 0);
+ if (DynBuf_GetSize(buf) == sizeof(int32)) {
+ memcpy(&x, (const char *)DynBuf_Get(buf), sizeof(int32));
+ } else {
+ break;
+ }
+
+ buf = DnDMsg_GetArg(&msg, 1);
+ if (DynBuf_GetSize(buf) == sizeof(int32)) {
+ memcpy(&y, (const char *)DynBuf_Get(buf), sizeof(int32));
+ } else {
+ break;
+ }
+ ghQueryPendingDragChanged.emit(x, y);
+ break;
+ }
+ case DND_GH_CANCEL:
+ ghCancelChanged.emit();
+ break;
+ case DND_HG_DRAG_ENTER:
+ {
+ CPClipboard clip;
+
+ /* Unserialize clipboard data for the command. */
+ buf = DnDMsg_GetArg(&msg, 0);
+ if (!CPClipboard_Unserialize(&clip, DynBuf_Get(buf), DynBuf_GetSize(buf))) {
+ Debug("%s: CPClipboard_Unserialize failed.\n", __FUNCTION__);
+ break;
+ }
+ hgDragEnterChanged.emit(&clip);
+ break;
+ }
+ case DND_HG_DRAG_START:
+ {
+ hgDragStartChanged.emit();
+ break;
+ }
+ case DND_HG_DROP:
+ hgDropChanged.emit();
+ break;
+ case DND_HG_CANCEL:
+ hgCancelChanged.emit();
+ break;
+ case DND_HG_FILE_COPY_DONE:
+ {
+ bool success;
+ std::vector<uint8> stagingDir;
+
+ buf = DnDMsg_GetArg(&msg, 0);
+ if (DynBuf_GetSize(buf) == sizeof(bool)) {
+ memcpy(&success, (const char *)DynBuf_Get(buf), sizeof(bool));
+ } else {
+ break;
+ }
+
+ buf = DnDMsg_GetArg(&msg, 1);
+ if (DynBuf_GetSize(buf) > 0) {
+ stagingDir.resize(DynBuf_GetSize(buf));
+ memcpy(&stagingDir[0],
+ (const char *)DynBuf_Get(buf),
+ stagingDir.size());
+ }
+ hgFileCopyDoneChanged.emit(success, stagingDir);
+ break;
+ }
+ default:
+ Debug("%s: got unsupported new command %d.\n",
+ __FUNCTION__, DnDMsg_GetCmd(&msg));
+ }
+exit:
+ DnDMsg_Destroy(&msg);
+}
* think once more.
*/
+#define ADFS_SUPER_MAGIC 0xADF5
#define AFFS_SUPER_MAGIC 0xADFF
#define EXT_SUPER_MAGIC 0x137D
#define EXT2_OLD_SUPER_MAGIC 0xEF51
#define EXT2_SUPER_MAGIC 0xEF53
+#define EXT3_SUPER_MAGIC 0xEF53
+#define EXT4_SUPER_MAGIC 0xEF53
#define HFSPLUS_SUPER_MAGIC 0x482B
#define NFS_SUPER_MAGIC 0x6969
#define SMB_SUPER_MAGIC 0x517B
+#define ISOFS_SUPER_MAGIC 0x9660
+#define JFFS2_SUPER_MAGIC 0x72B6
+#define PROC_SUPER_MAGIC 0x9FA0
+#define OPENPROM_SUPER_MAGIC 0x9FA1
+#define USBDEVICE_SUPER_MAGIC 0x9FA2
+#define AUTOFS_SUPER_MAGIC 0x0187
#if !defined(MSDOS_SUPER_MAGIC)
#define MSDOS_SUPER_MAGIC 0x4D44
#define VMFS_SUPER_MAGIC 0x2fABF15E
#define TMPFS_SUPER_MAGIC 0x01021994
#define JFS_SUPER_MAGIC 0x3153464A
+#define AFS_SUPER_MAGIC 0x5346414F
+#define CIFS_SUPER_MAGIC 0xFF534D42
#if !defined(REISERFS_SUPER_MAGIC)
#define REISERFS_SUPER_MAGIC 0x52654973
if (SMB_SUPER_MAGIC == sfbuf.f_type) {
return TRUE;
}
+ if (CIFS_SUPER_MAGIC == sfbuf.f_type) {
+ return TRUE;
+ }
return FALSE;
#endif
}
VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_TRANSFER_FINAL_DATA,
VIX_COMMAND_CATEGORY_PRIVILEGED),
+ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ADD_ROLLING_SNAPSHOT_TIER,
+ VIX_COMMAND_CATEGORY_PRIVILEGED),
+ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_ROLLING_SNAPSHOT_TIER,
+ VIX_COMMAND_CATEGORY_PRIVILEGED),
+ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_ROLLING_SNAPSHOT_TIER,
+ VIX_COMMAND_CATEGORY_PRIVILEGED),
+
+ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ADD_ROLLING_SNAPSHOT_TIER_VMX,
+ VIX_COMMAND_CATEGORY_PRIVILEGED),
+ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_ROLLING_SNAPSHOT_TIER_VMX,
+ VIX_COMMAND_CATEGORY_PRIVILEGED),
+ VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_ROLLING_SNAPSHOT_TIER_VMX,
+ VIX_COMMAND_CATEGORY_PRIVILEGED),
+
};
// To be safe, we always use 8 bytes.
#define PROPERTY_SIZE_POINTER 8
+static VixError VixPropertyListDeserializeImpl(VixPropertyListImpl *propList,
+ const char *buffer,
+ size_t bufferSize,
+ Bool clobber);
+
/*
*-----------------------------------------------------------------------------
*
*
* VixPropertyList_Deserialize --
*
+ * Deserialize a property list from a buffer. Repeated properties
+ * are clobbered.
+ *
+ * Results:
+ * VixError.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+VixError
+VixPropertyList_Deserialize(VixPropertyListImpl *propList, // IN
+ const char *buffer, // IN
+ size_t bufferSize) // IN
+{
+ return VixPropertyListDeserializeImpl(propList,
+ buffer,
+ bufferSize,
+ TRUE); // clobber
+} // VixPropertyList_Deserialize
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VixPropertyList_DeserializeNoClobber --
+ *
+ * Deserialize a property list from a buffer. Repeated properties
+ * are preserved.
+ *
+ * Results:
+ * VixError.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+VixError
+VixPropertyList_DeserializeNoClobber(VixPropertyListImpl *propList, // IN
+ const char *buffer, // IN
+ size_t bufferSize) // IN
+{
+ return VixPropertyListDeserializeImpl(propList,
+ buffer,
+ bufferSize,
+ FALSE); // clobber
+} // VixPropertyList_DeserializeNoClobber
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VixPropertyListDeserializeImpl --
+ *
* Deserialize a property list from a buffer.
*
* This function should be modified to deal with the case of
*/
VixError
-VixPropertyList_Deserialize(VixPropertyListImpl *propList, // IN
- const char *buffer, // IN
- size_t bufferSize) // IN
+VixPropertyListDeserializeImpl(VixPropertyListImpl *propList, // IN
+ const char *buffer, // IN
+ size_t bufferSize, // IN
+ Bool clobber) // IN
{
VixError err = VIX_OK;
VixPropertyValue *property = NULL;
pos += propertyTypeSize;
lengthPtr = (int*) &(buffer[pos]);
pos += propertyValueLengthSize;
-
+
/*
* Do not allow lengths of 0 or fewer bytes. Those do not make sense,
* unless you can pass a NULL blob, which Serialize() does not allow.
err = VIX_E_INVALID_SERIALIZED_DATA;
goto abort;
}
-
+
/*
* Create the property if missing
*/
- err = VixPropertyList_FindProperty(propList,
- *propertyIDPtr,
- *propertyTypePtr,
- 0, // index
- TRUE, //createIfMissing
- &property);
-
+ if (clobber) {
+ err = VixPropertyList_FindProperty(propList,
+ *propertyIDPtr,
+ *propertyTypePtr,
+ 0, // index
+ TRUE, //createIfMissing
+ &property);
+ } else {
+ err = VixPropertyListAppendProperty(propList,
+ *propertyIDPtr,
+ *propertyTypePtr,
+ &property);
+ }
+
if (VIX_OK != err) {
goto abort;
}
-
+
/*
* Initialize the property to the received value
*/
boolPtr = (Bool*) &(buffer[pos]);
property->value.boolValue = *boolPtr;
break;
-
+
////////////////////////////////////////////////////////
case VIX_PROPERTYTYPE_INT64:
if (PROPERTY_SIZE_INT64 != *lengthPtr) {
////////////////////////////////////////////////////////
default:
err = VIX_E_UNRECOGNIZED_PROPERTY;
- goto abort;
+ goto abort;
}
pos += *lengthPtr;
}
-abort:
+abort:
if ((VIX_OK != err) && (NULL != propList)) {
VixPropertyList_RemoveAllWithoutHandles(propList);
}
*/
static Bool GHITcloSetOutlookTempFolder(RpcInData* data);
+/*
+ * Wrapper function for the "ghi.guest.outlook.restore.tempFolder" RPC.
+ */
+static Bool GHITcloRestoreOutlookTempFolder(RpcInData* data);
+
+/*
+ * Wrapper function for the "ghi.guest.trashFolder.action" RPC.
+ */
+static Bool GHITcloTrashFolderAction(RpcInData *data);
+
+/*
+ * Wrapper function for the "ghi.guest.trashFolder.getIcon" RPC.
+ */
+static Bool GHITcloTrashFolderGetIcon(RpcInData *data);
+
static Bool GHIUpdateHost(GHIProtocolHandlerList *handlers);
DynBuf gTcloUpdate;
*/
if (GHI_IsSupported()) {
+ /* "Old-style callbacks. */
RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_BINARY_INFO,
GHITcloGetBinaryInfo, NULL);
- RpcIn_RegisterCallbackEx(rpcIn, UNITY_RPC_GET_BINARY_HANDLERS,
- GHITcloGetBinaryHandlers, NULL);
RpcIn_RegisterCallback(rpcIn, UNITY_RPC_OPEN_LAUNCHMENU,
GHITcloOpenStartMenu, NULL);
RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_LAUNCHMENU_ITEM,
GHITcloShellOpen, NULL);
RpcIn_RegisterCallback(rpcIn, GHI_RPC_GUEST_SHELL_ACTION,
GHITcloShellAction, NULL);
+
+ /* "New-style" callbacks. */
+ RpcIn_RegisterCallbackEx(rpcIn, UNITY_RPC_GET_BINARY_HANDLERS,
+ GHITcloGetBinaryHandlers, NULL);
RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_SET_GUEST_HANDLER,
GHITcloSetGuestHandler, NULL);
RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_RESTORE_DEFAULT_GUEST_HANDLER,
GHITcloRestoreDefaultGuestHandler, NULL);
RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_OUTLOOK_SET_TEMP_FOLDER,
GHITcloSetOutlookTempFolder, NULL);
+ RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_OUTLOOK_RESTORE_TEMP_FOLDER,
+ GHITcloRestoreOutlookTempFolder, NULL);
+ RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_TRASH_FOLDER_ACTION,
+ GHITcloTrashFolderAction, NULL);
+ RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_TRASH_FOLDER_GET_ICON,
+ GHITcloTrashFolderGetIcon, NULL);
}
}
__FUNCTION__, data->name, data->argsSize);
/*
- * Build an XDR Stream from the argument data.
+ * Build an XDR stream from the argument data.
*
* Note that the argument data begins with args + 1 since there is a space
* between the RPC name and the XDR serialization.
return ret;
}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * GHITcloRestoreOutlookTempFolder --
+ *
+ * Handler for the 'ghi.guest.outlook.restore.tempFolder' RPC.
+ *
+ * Results:
+ * If the RPC fails, return FALSE. Otherwise, returns TRUE.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static Bool
+GHITcloRestoreOutlookTempFolder(RpcInData *data) // IN/OUT: RPC data
+{
+ Bool ret = FALSE;
+
+ Debug("%s: Enter.\n", __FUNCTION__);
+
+ // Check our arguments. Note that this RPC doesn't have any arguments!
+ ASSERT(data);
+ ASSERT(data->name);
+ ASSERT(data->argsSize == 0);
+
+ if (!(data && data->name && data->argsSize == 0)) {
+ Debug("%s: Invalid arguments.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
+ __FUNCTION__, data->name, data->argsSize);
+
+ // Call the platform implementation of our RPC.
+ ret = GHIPlatformRestoreOutlookTempFolder(ghiPlatformData);
+
+ if (ret == FALSE) {
+ Debug("%s: Failed to set Outlook temporary folder.\n", __FUNCTION__);
+ RPCIN_SETRETVALS(data, "Failed to set Outlook temporary folder", FALSE);
+ goto exit;
+ }
+
+ /*
+ * We don't have any out parameters, so we write empty values into the
+ * result fields of the RpcInData structure.
+ */
+ RPCIN_SETRETVALS(data, "", FALSE);
+
+ // Set our return value and return to the caller.
+ ret = TRUE;
+
+exit:
+ Debug("%s: Exit.\n", __FUNCTION__);
+ return ret;
+}
+
+
+/**
+ * @brief Wrapper function for the ghi.guest.trashFolder.action RPC.
+ *
+ * params[in] data Pointer to the RpcInData structure for the RPC.
+ *
+ * @retval TRUE The RPC succeeded.
+ * @retval FALSE The RPC failed.
+ */
+
+Bool
+GHITcloTrashFolderAction(RpcInData *data)
+{
+ Bool ret = FALSE;
+ XDR xdrs;
+
+ Debug("%s: Enter.\n", __FUNCTION__);
+
+ /* Check our arguments. */
+ ASSERT(data);
+ ASSERT(data->name);
+ ASSERT(data->argsSize > 0);
+
+ if (!(data && data->name && data->argsSize > 0)) {
+ Debug("%s: Invalid arguments.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
+ __FUNCTION__, data->name, data->argsSize);
+
+ /*
+ * Build an XDR stream from the argument data.
+ *
+ * Note that the argument data begins with args + 1 since there is a space
+ * between the RPC name and the XDR serialization.
+ */
+ xdrmem_create(&xdrs, (char*) data->args + 1, data->argsSize - 1, XDR_DECODE);
+
+ /* Call the platform implementation of our RPC. */
+ ret = GHIPlatformTrashFolderAction(ghiPlatformData, &xdrs);
+
+ /* Destroy the XDR stream. */
+ xdr_destroy(&xdrs);
+
+ if (ret == FALSE) {
+ Debug("%s: RPC failed.\n", __FUNCTION__);
+ RPCIN_SETRETVALS(data, "RPC failed", FALSE);
+ goto exit;
+ }
+
+ /*
+ * We don't have any out parameters, so we write empty values into the
+ * result fields of the RpcInData structure.
+ */
+ RPCIN_SETRETVALS(data, "", FALSE);
+
+ /* Set our return value and return to the caller. */
+ ret = TRUE;
+
+exit:
+ Debug("%s: Exit.\n", __FUNCTION__);
+ return ret;
+}
+
+
+/**
+ * @brief Send the ghi.guest.trashFolder.state RPC to the host.
+ *
+ * Send the ghi.guest.trashFolder.state RPC to the host. This function is used
+ * by the platform-specific GHI backends to notify the host when the state of
+ * the Trash (aka Recycle Bin) folder changes. Currently, the only information
+ * sent using this RPC is the empty/non-empty state of the Trash folder.
+ *
+ * @params[in] xdrs Pointer to XDR serialized arguments.
+ *
+ * @retval TRUE The RPC was sent successfully.
+ * @retval FALSE The RPC was not sent.
+ */
+
+Bool
+GHISendTrashFolderStateRPC(XDR *xdrs)
+{
+ Bool ret = FALSE;
+ DynBuf outBuf;
+
+ Debug("%s: Enter.\n", __FUNCTION__);
+
+ /* Check our arguments. */
+ ASSERT(xdrs);
+
+ if (NULL == xdrs) {
+ Debug("%s: Invalid parameter.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ DynBuf_Init(&outBuf);
+
+ /* Append our RPC name and a space to the DynBuf. */
+ if (!DynBuf_Append(&outBuf,
+ GHI_RPC_TRASH_FOLDER_STATE,
+ strlen(GHI_RPC_TRASH_FOLDER_STATE))) {
+ Debug("%s: Failed to append RPC name to DynBuf.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ if (!DynBuf_Append(&outBuf, " ", 1)) {
+ Debug("%s: Failed to append space to DynBuf.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /* Append the XDR serialized data to the DynBuf. */
+ if (!DynBuf_Append(&outBuf, DynXdr_Get(xdrs), xdr_getpos(xdrs)) )
+ {
+ Debug("%s: Failed to append XDR serialized data to DynBuf.\n",
+ __FUNCTION__);
+ goto exit;
+ }
+
+ if (!RpcOut_SendOneRaw(DynBuf_Get(&outBuf),
+ DynBuf_GetSize(&outBuf),
+ NULL,
+ NULL)) {
+ Debug("%s: Failed to send RPC to host!\n", __FUNCTION__);
+ goto exit;
+ }
+
+ ret = TRUE;
+
+exit:
+ DynBuf_Destroy(&outBuf);
+ Debug("%s: Exit.\n", __FUNCTION__);
+ return ret;
+}
+
+/**
+ * @brief Return the icon for the Trash folder (aka Recycle Bin) to the host.
+ *
+ * Get the icon for the Trash Folder (aka Recycle Bin) and return it to the
+ * host.
+ *
+ * @param[in] data Pointer to the RpcInData structure for the RPC.
+ *
+ * @retval TRUE The RPC succeeded.
+ * @retval FALSE The RPC failed.
+ */
+
+Bool
+GHITcloTrashFolderGetIcon(RpcInData *data)
+{
+ Bool ret = FALSE;
+ XDR xdrs;
+
+ Debug("%s: Enter.\n", __FUNCTION__);
+
+ /* Check our arguments. */
+ ASSERT(data);
+ ASSERT(data->name);
+
+ if (!(data && data->name)) {
+ Debug("%s: Invalid arguments.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
+ __FUNCTION__, data->name, data->argsSize);
+
+ /* Create the XDR structure we'll use for the output of the RPC. */
+ if (NULL == DynXdr_Create(&xdrs)) {
+ Debug("%s: Failed to create DynXdr structure.\n", __FUNCTION__);
+ RPCIN_SETRETVALS(data, "Failed to create XDR structure", FALSE);
+ goto exit;
+ }
+
+ /* Call the platform code to get the icon data. */
+ if (!GHIPlatformTrashFolderGetIcon(ghiPlatformData, &xdrs)) {
+ Debug("%s: Failed to get Trash folder icon.\n", __FUNCTION__);
+ RPCIN_SETRETVALS(data, "Failed to get Trash folder icon", FALSE);
+ goto exit;
+ }
+
+ /*
+ * If the serialized data exceeds our maximum message size we have little
+ * choice but to fail the request and log the oversize message.
+ *
+ * XXX Shouldn't the RPC layer enforce the maximum message size?
+ */
+ if (xdr_getpos(&xdrs) > GUESTMSG_MAX_IN_SIZE) {
+ Debug("%s: Maximum message size exceeced! Got %d bytes of icon data.\n",
+ __FUNCTION__, xdr_getpos(&xdrs));
+ RPCIN_SETRETVALS(data, "Trash folder icon too large", FALSE);
+ goto exit;
+ }
+
+ /*
+ * Write the result into the RPC out parameters.
+ */
+ data->result = DynXdr_Get(&xdrs);
+ data->resultLen = xdr_getpos(&xdrs);
+ data->freeResult = TRUE;
+
+ ret = TRUE;
+
+exit:
+ /*
+ * If we were successful, then don't free the contents of the DynXdr; the
+ * buffer will be freed by the RPC layer.
+ */
+ DynXdr_Destroy(&xdrs, !ret);
+ return ret;
+}
*/
Bool GHIPlatformSetOutlookTempFolder(GHIPlatform* ghip, const XDR* xdrs);
+/*
+ * Restore the temporary folder used by Outlook to store attachments.
+ */
+Bool GHIPlatformRestoreOutlookTempFolder(GHIPlatform* ghip);
+
+/*
+ * Perform an action on the Trash (aka Recycle Bin) folder, such as opening it
+ * or emptying it.
+ */
+Bool GHIPlatformTrashFolderAction(GHIPlatform* ghip, const XDR *xdrs);
+
+/* Get the icon for the Trash (aka Recycle Bin) folder. */
+Bool GHIPlatformTrashFolderGetIcon(GHIPlatform *ghip, XDR *xdrs);
/* Implemented by ghIntegration.c for use by the platform-specific code */
Bool GHILaunchMenuChangeRPC(void);
+/*
+ * Used by the platform-specific code to send the "tools.ghi.trash.change" RPC
+ * to the host.
+ */
+Bool GHISendTrashFolderStateRPC(XDR *xdrs);
+
#endif
int nextMenuHandle;
GHashTable *menuHandles;
- GHashTable *vmwareEnv;
+
+ /** Pre-wrapper script environment. See @ref System_GetNativeEnviron. */
+ const char **nativeEnviron;
};
#ifdef GTK2
static void GHIPlatformSetMenuTracking(GHIPlatform *ghip,
Bool isEnabled);
static char *GHIPlatformUriPathToString(UriPathSegmentA *path);
-static Bool GHIRestoreVMwareEnviron(GHIPlatform *ghip);
-static Bool GHISetVMwareEnviron(GHIPlatform *ghip);
/*
GHIPlatformInit(VMU_ControllerCB *vmuControllerCB, // IN
void *ctx) // IN
{
+ extern const char **environ;
GHIPlatform *ghip;
ghip = Util_SafeCalloc(1, sizeof *ghip);
ghip->directoriesTracked = g_array_new(FALSE, FALSE, sizeof(GHIDirectoryWatch));
+ ghip->nativeEnviron = System_GetNativeEnviron(environ);
AppUtil_Init();
return ghip;
return TRUE;
}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHIPlatformFreeKeyAndValue --
- *
- * Frees a hash table entry. Typically called from a g_hashtable
- * iterator. Both the key, and the value are freed.
- *
- * Results:
- * TRUE always.
- *
- * Side effects:
- * The specified value will no longer be valid.
- *
- *-----------------------------------------------------------------------------
- */
-
-static gboolean
-GHIPlatformFreeKeyAndValue(gpointer key, // IN
- gpointer value, // IN
- gpointer user_data) // IN
-{
- g_free(key);
- g_free(value);
-
- return TRUE;
-}
#endif // GTK2
GHIPlatformSetMenuTracking(ghip, FALSE);
g_array_free(ghip->directoriesTracked, TRUE);
ghip->directoriesTracked = NULL;
- if (ghip->vmwareEnv) {
- g_hash_table_foreach_remove(ghip->vmwareEnv, GHIPlatformFreeKeyAndValue, NULL);
- g_hash_table_destroy(ghip->vmwareEnv);
- ghip->vmwareEnv = NULL;
+ if (ghip->nativeEnviron) {
+ System_FreeNativeEnviron(ghip->nativeEnviron);
+ ghip->nativeEnviron = NULL;
}
free(ghip);
}
if (GHIPlatformCombineArgs(ghip, fileUtf8, &fullArgv, &fullArgc) &&
fullArgc > 0) {
- GHIRestoreVMwareEnviron(ghip);
- retval = g_spawn_async(NULL, fullArgv, NULL,
+ retval = g_spawn_async(NULL, fullArgv,
+ /*
+ * XXX Please don't hate me for casting off the qualifier
+ * here. Glib does -not- modify the environment, at
+ * least not in the parent process, but their prototype
+ * does not specify this argument as being const.
+ *
+ * Comment stolen from GuestAppX11OpenUrl.
+ */
+ (char **)ghip->nativeEnviron,
G_SPAWN_SEARCH_PATH |
G_SPAWN_STDOUT_TO_DEV_NULL |
G_SPAWN_STDERR_TO_DEV_NULL,
NULL, NULL, NULL, NULL);
- GHISetVMwareEnviron(ghip);
}
g_strfreev(fullArgv);
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*
- * GHISetVMwareVariable --
+ * GHIPlatformSetOutlookTempFolder --
+ *
+ * Set the temporary folder used by Microsoft Outlook to store attachments
+ * opened by the user.
*
- * Sets the environment variable passed in to the value passed in.
+ * XXX While we probably won't ever need to implement this for Linux, we
+ * still the definition of this function in the X11 back-end.
*
* Results:
- * None.
+ * TRUE if successful, FALSE otherwise.
*
* Side effects:
- * The specified environment variable is set.
+ * None
*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*/
-static void
-GHISetVMwareVariable(gpointer key, // IN
- gpointer value, // IN
- gpointer user_data) // IN (unused)
+Bool
+GHIPlatformSetOutlookTempFolder(GHIPlatform *ghip, // IN: platform-specific state
+ const XDR *xdrs) // IN: XDR Serialized arguments
{
- if (value) {
- System_SetEnv(TRUE, key, value);
- } else {
- System_UnsetEnv(key);
- }
+ ASSERT(ghip);
+ ASSERT(xdrs);
+
+ return FALSE;
}
/*
- *------------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*
- * GHIRestoreVMwareEnviron --
+ * GHIPlatformRestoreOutlookTempFolder --
*
- * For each VMWARE_FOO in the environment, putenv its value as FOO
- * and save off the previous value of FOO for later restore (iff this
- * is the first time we are called, e.g., the hash table was not yet
- * created.) This is called by GHIPlatformShellOpen on Linux only to
- * undo what the vmwareuser wrapper script did to the environment,
- * before we fork and exec.
+ * Set the temporary folder used by Microsoft Outlook to store attachments
+ * opened by the user.
*
* Results:
- * TRUE on success
- * FALSE on error
+ * TRUE if successful, FALSE otherwise.
*
* Side effects:
- * None
+ * None
*
- *------------------------------------------------------------------------------
+ *----------------------------------------------------------------------------
*/
-static Bool
-GHIRestoreVMwareEnviron(GHIPlatform *ghip) // IN
+Bool
+GHIPlatformRestoreOutlookTempFolder(GHIPlatform *ghip) // IN: platform-specific state
{
- extern char **environ;
- char **p;
- Bool addToHash = FALSE;
-
- if (!ghip->vmwareEnv) {
- ghip->vmwareEnv = g_hash_table_new(g_str_hash, g_str_equal);
- addToHash = TRUE;
- }
-
- if (!ghip->vmwareEnv) {
- return FALSE;
- }
-
- for (p = environ; p && *p; p++) {
- char *lhs;
- char *rhs;
- unsigned int index;
-
- if (!StrUtil_StartsWith(*p, "VMWARE_")) {
- continue;
- }
+ ASSERT(ghip);
- /*
- * So we have a variable that starts with VMWARE_. This variable
- * was created by the wrapper script that launches us, for each
- * variable in the parent environment it modified. For example, if
- * the variable it changes is LD_LIBRARY_PATH, then the variable
- * VMWARE_LD_LIBRARY_PATH will hold the value before the wrapper
- * script modified it. In Unix, we get this variable in the
- * environ extern as VMWARE_LD_LIBRARY_PATH=value. So, we want to
- * get the lhs of the "=", skip past the VMWARE_ prefix to get to
- * the variable name, and extract the rhs of the "=" to get the
- * value.
- */
- index = 0;
- lhs = StrUtil_GetNextToken(&index, *p, "=");
- if (lhs) {
- index++;
- rhs = StrUtil_GetNextToken(&index, *p, "");
- if (rhs && *rhs) {
- char *q;
- q = lhs + sizeof "VMWARE_" - 1;
- if (*q) {
- Debug("%s: restoring %s\n", __FUNCTION__, q);
- if (addToHash) {
- g_hash_table_insert(ghip->vmwareEnv, g_strdup(q),
- System_GetEnv(TRUE, q));
- }
- /*
- * If the value is "0", the script told us that
- * there was no corresponding variable in the
- * environment. XXX why it was compelled to create
- * the VMWARE_ counterpart is unclear. It should have
- * been set with a value like "VMWARE_UNSET_ENV"
- * because "0" is conceivably a value that is legit
- * in some instances. Here, we assume no legit var
- * had a value of "0". See bug 313450.
- */
- if (strcmp(rhs, "0") == 0) {
- System_UnsetEnv(q);
- } else if (*rhs == '1') {
- System_SetEnv(TRUE, q, rhs + 1);
- }
- }
- }
- free(rhs);
- }
- free(lhs);
- }
- return TRUE;
+ return FALSE;
}
-/*
- *------------------------------------------------------------------------------
+/**
+ * @brief Performs an action on the Trash (aka Recycle Bin) folder.
*
- * GHISetVMwareEnviron --
+ * Performs an action on the Trash (aka Recycle Bin) folder. Currently, the
+ * only supported actions are to open the folder, or empty it.
*
- * Restore each environment variable in the hash table to the values
- * assigned by the wrapper script when vmware-user was executed.
+ * @param[in] ghip Pointer to platform-specific GHI data.
+ * @param[in] xdrs Pointer to XDR serialized arguments.
*
- * Results:
- * TRUE on success
- * FALSE on error
- *
- * Side effects:
- * None
- *
- *------------------------------------------------------------------------------
+ * @retval TRUE The action was performed.
+ * @retval FALSE The action couldn't be performed.
*/
-static Bool
-GHISetVMwareEnviron(GHIPlatform *ghip) // IN
+Bool
+GHIPlatformTrashFolderAction(GHIPlatform *ghip,
+ const XDR *xdrs)
{
- if (!ghip->vmwareEnv) {
- return FALSE;
- }
- g_hash_table_foreach(ghip->vmwareEnv, GHISetVMwareVariable, NULL);
- return TRUE;
+ ASSERT(ghip);
+ ASSERT(xdrs);
+ return FALSE;
}
-/*
- *----------------------------------------------------------------------------
+/* @brief Returns the icon of the Trash (aka Recycle Bin) folder.
*
- * GHIPlatformSetOutlookTempFolder --
+ * Gets the icon of the Trash (aka Recycle Bin) folder, and returns it
+ * to the host.
*
- * Set the temporary folder used by Microsoft Outlook to store attachments
- * opened by the user.
+ * @param[in] ghip Pointer to platform-specific GHI data.
+ * @param[out] xdrs Pointer to XDR serialized data to send to the host.
*
- * XXX While we probably won't ever need to implement this for Linux, we
- * still the definition of this function in the X11 back-end.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
+ * @retval TRUE The icon was fetched successfully.
+ * @retval FALSE The icon could not be fetched.
*/
Bool
-GHIPlatformSetOutlookTempFolder(GHIPlatform *ghip, // IN: platform-specific state
- const XDR *xdrs) // IN: XDR Serialized arguments
+GHIPlatformTrashFolderGetIcon(GHIPlatform *ghip,
+ XDR *xdrs)
{
ASSERT(ghip);
ASSERT(xdrs);
-
return FALSE;
}
-
libGuestInfo_la_SOURCES =
libGuestInfo_la_SOURCES += guestInfo.c
-libGuestInfo_la_SOURCES += guestInfoServer.c
libGuestInfo_la_SOURCES += guestInfoPosix.c
-libGuestInfo_la_SOURCES += guestInfoPerfMonLinux.c
-
-noinst_LTLIBRARIES += libGuestInfoCS.la
-
-libGuestInfoCS_la_SOURCES =
-libGuestInfoCS_la_SOURCES += guestInfo.c
-libGuestInfoCS_la_SOURCES += guestInfoPosix.c
AM_CFLAGS = $(DNET_CPPFLAGS)
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * This file gathers the virtual memory stats from Linux guest to be
- * passed on to the vmx.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <string.h>
-
-#include "vmware.h"
-#include "guestInfo.h"
-#include "strutil.h"
-#include "debug.h"
-
-#ifndef NO_PROCPS
-#include "vm_procps.h"
-static void GuestInfoMonitorGetStat(GuestMemInfo *vmStats);
-static Bool GuestInfoMonitorReadMeminfo(GuestMemInfo *vmStats);
-#endif
-
-#define LINUX_MEMINFO_FLAGS (MEMINFO_MEMTOTAL | MEMINFO_MEMFREE | MEMINFO_MEMBUFF |\
- MEMINFO_MEMCACHE | MEMINFO_MEMACTIVE | MEMINFO_MEMINACTIVE |\
- MEMINFO_SWAPINRATE | MEMINFO_SWAPOUTRATE |\
- MEMINFO_IOINRATE | MEMINFO_IOOUTRATE)
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestInfo_PerfMon --
- *
- * Gather performance stats.
- *
- * Results:
- * Gathered stats. Returns FALSE on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-GuestInfo_PerfMon(GuestMemInfo *vmStats) // OUT: filled vmstats
-{
-#ifndef NO_PROCPS
- ASSERT(vmStats);
- vmStats->flags = 0;
- GuestInfoMonitorGetStat(vmStats);
- if (GuestInfoMonitorReadMeminfo(vmStats)) {
- vmStats->flags |= LINUX_MEMINFO_FLAGS;
- return TRUE;
- }
-#endif
- return FALSE;
-}
-
-
-#ifndef NO_PROCPS
-/*
- *----------------------------------------------------------------------
- *
- * GuestInfoMonitorGetStat --
- *
- * Calls getstat() to gather memory stats.
- *
- * Results:
- * Gathered stats in vmStats.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-GuestInfoMonitorGetStat(GuestMemInfo *vmStats) // OUT: filled vmstats
-{
- uint32 hz = Hertz;
- uint32 dummy;
- jiff cpuUse[2];
- jiff cpuNic[2];
- jiff cpuSys[2];
- jiff cpuIdl[2];
- jiff cpuIow[2];
- jiff cpuXxx[2];
- jiff cpuYyy[2];
- jiff cpuZzz[2];
- jiff cpuTotal;
- jiff cpuHalf;
- unsigned long pageIn[2];
- unsigned long pageOut[2];
- unsigned long swapIn[2];
- unsigned long swapOut[2];
- unsigned int dummy2[2];
- unsigned long kb_per_page = sysconf(_SC_PAGESIZE) / 1024ul;
-
- meminfo();
- getstat(cpuUse, cpuNic, cpuSys, cpuIdl, cpuIow, cpuXxx, cpuYyy, cpuZzz,
- pageIn, pageOut, swapIn, swapOut, dummy2, dummy2, &dummy, &dummy,
- &dummy, &dummy);
-
- cpuTotal = *cpuUse + *cpuNic + *cpuSys + *cpuXxx +
- *cpuYyy + *cpuIdl + *cpuIow + *cpuZzz;
- cpuHalf = cpuTotal / 2UL;
-
- vmStats->memFree = kb_main_free;
- vmStats->memBuff = kb_main_buffers;
- vmStats->memCache = kb_main_cached,
- vmStats->memInactive = kb_inactive;
- vmStats->memActive = kb_active;
-
- vmStats->swapInRate = (uint64)((*swapIn * kb_per_page * hz + cpuHalf) / cpuTotal);
- vmStats->swapOutRate = (uint64)((*swapOut * kb_per_page * hz + cpuHalf) / cpuTotal);
- vmStats->ioInRate = (uint64)((*pageIn * kb_per_page * hz + cpuHalf) / cpuTotal);
- vmStats->ioOutRate = (uint64)((*pageOut * kb_per_page * hz + cpuHalf) / cpuTotal);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestInfoMonitorReadMeminfo --
- *
- * Reads /proc/meminfo to gather phsycial memory and huge page stats.
- *
- * Results:
- * Read /proc/meminfo for total physical memory and huge pages info.
- * Returns FALSE on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static Bool
-GuestInfoMonitorReadMeminfo(GuestMemInfo *vmStats) // OUT: filled vmstats
-{
- char buf[512];
- uint64 value;
- FILE *fp;
-
- /* Get the total memory, and huge page info from /proc/meminfo. */
- fp = fopen("/proc/meminfo", "r");
- if (!fp) {
- Log("GuestInfoMonitorReadMeminfo: Error opening /proc/meminfo.\n");
- return FALSE;
- }
-
- while(!feof(fp)) {
- if (fscanf(fp, "%s %"FMT64"u", buf, &value) != 2) {
- continue;
- }
- if (StrUtil_StartsWith(buf, "MemTotal")) {
- vmStats->memTotal = value;
- }
- if (StrUtil_StartsWith(buf, "HugePages_Total")) {
- vmStats->hugePagesTotal = value;
- vmStats->flags |= MEMINFO_HUGEPAGESTOTAL;
- }
- if (StrUtil_StartsWith(buf, "HugePages_Free")) {
- vmStats->hugePagesFree = value;
- vmStats->flags |= MEMINFO_HUGEPAGESFREE;
- }
- }
- fclose(fp);
- return TRUE;
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * guestInfoServer.c --
- *
- * This is the implementation of the common code in the guest tools
- * to send out guest information to the host. The guest info server
- * runs in the context of the tools daemon's event loop and periodically
- * gathers all guest information and sends updates to the host if required.
- * This file implements the platform independent framework for this.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <limits.h>
-
-#include "vmware.h"
-#include "eventManager.h"
-#include "debug.h"
-#include "dynxdr.h"
-#include "str.h"
-#include "util.h"
-#include "rpcout.h"
-#include "rpcvmx.h"
-#include "hostinfo.h"
-#include "guestInfo.h"
-#include "guestApp.h"
-#include "guestInfoServer.h"
-#include "guestInfoInt.h"
-#include "buildNumber.h"
-#include "system.h"
-#include "guest_msg_def.h" // For GUESTMSG_MAX_IN_SIZE
-#include "xdrutil.h"
-#include "wiper.h"
-
-#define GUESTINFO_DEFAULT_DELIMITER ' '
-
-/*
- * Stores information about all guest information sent to the vmx.
- */
-
-typedef struct _GuestInfoCache{
- char value[INFO_MAX][MAX_VALUE_LEN]; /* Stores values of all key-value pairs. */
- GuestNicList nicInfo;
- GuestDiskInfo diskInfo;
-} GuestInfoCache;
-
-
-/*
- * Local variables.
- */
-static uint32 gDisableQueryDiskInfo = FALSE;
-
-static DblLnkLst_Links *gGuestInfoEventQueue;
-/* Local cache of the guest information that was last sent to vmx. */
-static GuestInfoCache gInfoCache;
-
-/*
- * A boolean flag that specifies whether the state of the VM was
- * changed since the last time guest info was sent to the VMX.
- * Tools daemon sets it to TRUE after the VM was resumed.
- */
-
-static Bool vmResumed;
-
-static Bool GuestInfoGather(void * clientData);
-static Bool GuestInfoUpdateVmdb(GuestInfoType infoType, void* info);
-static Bool SetGuestInfo(GuestInfoType key, const char* value, char delimiter);
-static Bool NicInfoChanged(GuestNicList *nicInfo);
-static Bool DiskInfoChanged(PGuestDiskInfo diskInfo);
-static void GuestInfoClearCache(void);
-static int PrintNicInfo(GuestNicList *nicInfo, int (*PrintFunc)(const char *, ...));
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestInfoServer_Init --
- *
- * Initialize some variables and add the first event to the queue.
- *
- * Call GuestInfoServer_Cleanup() to do the necessary cleanup.
- *
- * Result
- * TRUE on success, FALSE on failure.
- *
- * Side-effects
- * The timer event queue is populated with the first event.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-GuestInfoServer_Init(DblLnkLst_Links *eventQueue) // IN: queue for event loop
-{
- Debug("Entered guest info init.\n");
- ASSERT(eventQueue);
-
- memset(&gInfoCache, 0, sizeof gInfoCache);
- vmResumed = FALSE;
- gGuestInfoEventQueue = eventQueue;
-
- /* Add the first timer event. */
- if (!EventManager_Add(gGuestInfoEventQueue, GUESTINFO_TIME_INTERVAL_MSEC,
- GuestInfoGather, NULL)) {
- Debug("Unable to add initial event.\n");
- return FALSE;
- }
-
- /* Initialize the wiper library. */
- if (!Wiper_Init(NULL)) {
- Debug("GetDiskInfo: ERROR: could not initialize wiper library\n");
- gDisableQueryDiskInfo = TRUE;
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestInfoServer_DisableDiskInfoQuery --
- *
- * Set whether to disable/enable querying disk information.
- * This function is required to provide a work around for bug number 94434.
- * On Win 9x/ME querying for the disk information prevents the machine from
- * entering standby. So we added a configuration option diable-query-diskinfo
- * for the tools.conf file. We use this function to let the guestd & tools service
- * control the disabling/enabling of disk information querying.
- *
- * Result
- * None.
- *
- * Side-effects
- * GuestInfoGather ignores disk information querying if this is called with TRUE.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-GuestInfoServer_DisableDiskInfoQuery(Bool disable)
-{
- gDisableQueryDiskInfo = disable;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestInfoServer_Cleanup --
- *
- * Cleanup initialized values.
- *
- * Result
- * None.
- *
- * Side-effects
- * Deallocates any memory allocated in gInfoCache.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-GuestInfoServer_Cleanup(void)
-{
- GuestInfoClearCache();
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestInfoServer_VMResumedNotify --
- *
- * Called by the tools daemon to notify of the VM's state change.
- * Right now this function is called after the VM was resumed.
- *
- * Result
- * None.
- *
- * Side-effects
- * vmResumed is set to TRUE.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-GuestInfoServer_VMResumedNotify(void)
-{
- vmResumed = TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestInfoGather --
- *
- * Periodically collects all the desired guest information and updates VMDB.
- *
- * Result
- * TRUE always. Even if some of the values were not updated, continue running.
- *
- * Side-effects
- * VMDB is updated if the given value has changed.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-GuestInfoGather(void *clientData) // IN: unused
-{
- char name[255];
- char osNameFull[MAX_VALUE_LEN];
- char osName[MAX_VALUE_LEN];
- GuestNicList nicInfo;
- GuestDiskInfo diskInfo;
-#if defined(_WIN32) || defined(linux)
- GuestMemInfo vmStats = {0};
-#endif
-
- Debug("Entered guest info gather.\n");
-
- memset(&nicInfo, 0, sizeof nicInfo);
-
- /* Send tools version. */
- if (!GuestInfoUpdateVmdb(INFO_BUILD_NUMBER, BUILD_NUMBER)) {
- /*
- * An older vmx talking to new tools wont be able to handle
- * this message. Continue, if thats the case.
- */
-
- Debug("Failed to update VMDB with tools version.\n");
- }
-
- /* Gather all the relevant guest information. */
- if (!Hostinfo_GetOSName(sizeof osNameFull, sizeof osName, osNameFull,
- osName)) {
- Debug("Failed to get OS info.\n");
- } else {
- if (!GuestInfoUpdateVmdb(INFO_OS_NAME_FULL, osNameFull)) {
- Debug("Failed to update VMDB\n");
- }
- if (!GuestInfoUpdateVmdb(INFO_OS_NAME, osName)) {
- Debug("Failed to update VMDB\n");
- }
- }
-
- if (!gDisableQueryDiskInfo) {
- if (!GuestInfoGetDiskInfo(&diskInfo)) {
- Debug("Failed to get disk info.\n");
- } else {
- if (!GuestInfoUpdateVmdb(INFO_DISK_FREE_SPACE, &diskInfo)) {
- Debug("Failed to update VMDB\n.");
- }
- }
- /* Free memory allocated in GuestInfoGetDiskInfo. */
- if (diskInfo.partitionList != NULL) {
- free(diskInfo.partitionList);
- diskInfo.partitionList = NULL;
- }
- }
-
- if(!GuestInfoGetFqdn(sizeof name, name)) {
- Debug("Failed to get netbios name.\n");
- } else {
- if (!GuestInfoUpdateVmdb(INFO_DNS_NAME, name)) {
- Debug("Failed to update VMDB.\n");
- }
- }
-
- /* Get NIC information. */
- if (!GuestInfoGetNicInfo(&nicInfo)) {
- Debug("Failed to get nic info.\n");
- } else if (NicInfoChanged(&nicInfo)) {
- if (GuestInfoUpdateVmdb(INFO_IPADDRESS, &nicInfo)) {
- /*
- * Update the cache. Release the memory previously used by the cache,
- * and copy the new information into the cache.
- */
- VMX_XDR_FREE(xdr_GuestNicList, &gInfoCache.nicInfo);
- gInfoCache.nicInfo = nicInfo;
- } else {
- Debug("Failed to update VMDB.\n");
- }
- } else {
- Debug("Nic info not changed.\n");
- VMX_XDR_FREE(xdr_GuestNicList, &nicInfo);
- }
-
- /* Send the uptime to VMX so that it can detect soft resets. */
- if (!GuestInfoServer_SendUptime()) {
- Debug("Failed to update VMDB with uptime.\n");
- }
-
-#if defined(_WIN32) || defined(linux)
- /* Send the vmstats to the VMX. */
-
- if (!GuestInfo_PerfMon(&vmStats)) {
- Debug("Failed to get vmstats.\n");
- } else {
- vmStats.version = 1;
- if (!GuestInfoUpdateVmdb(INFO_MEMORY, &vmStats)) {
- Debug("Failed to send vmstats.\n");
- }
- }
-#endif
-
- /*
- * Even if one of the updates was unsuccessfull,
- * we still add the next timer event. This way
- * if one of the pieces failed, other information will
- * still be passed to the host.
- *
- */
- if (!EventManager_Add(gGuestInfoEventQueue, GUESTINFO_TIME_INTERVAL_MSEC,
- GuestInfoGather, NULL)) {
- Debug("GuestInfoGather: Unable to add next event.\n");
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestInfoConvertNicInfoToNicInfoV1 --
- *
- * Convert the new dynamic nicInfoNew to fixed size struct GuestNicInfoV1.
- *
- * Results:
- * TRUE if successfully converted
- * FALSE otherwise
- *
- * Side effects:
- * If number of NICs or number of IP addresses on any of the NICs
- * exceeding MAX_NICS and MAX_IPS respectively, the extra ones
- * are truncated, on successful return.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-GuestInfoConvertNicInfoToNicInfoV1(GuestNicList *info, // IN
- GuestNicInfoV1 *infoV1) // OUT
-{
- uint32 maxNics;
- u_int i;
-
- if ((NULL == info) ||
- (NULL == infoV1)) {
- return FALSE;
- }
-
- maxNics = MIN(info->nics.nics_len, MAX_NICS);
- infoV1->numNicEntries = maxNics;
- if (maxNics < info->nics.nics_len) {
- Debug("GuestInfo: truncating NIC list for backwards compatibility.\n");
- }
-
- XDRUTIL_FOREACH(i, info, nics) {
- u_int j;
- uint32 maxIPs;
- GuestNic *nic = XDRUTIL_GETITEM(info, nics, i);
-
- Str_Strcpy(infoV1->nicList[i].macAddress,
- nic->macAddress,
- sizeof infoV1->nicList[i].macAddress);
-
- maxIPs = MIN(nic->ips.ips_len, MAX_IPS);
- infoV1->nicList[i].numIPs = 0;
-
- XDRUTIL_FOREACH(j, nic, ips) {
- VmIpAddress *ip = XDRUTIL_GETITEM(nic, ips, j);
-
- if (strlen(ip->ipAddress) < sizeof infoV1->nicList[i].ipAddress[j]) {
- Str_Strcpy(infoV1->nicList[i].ipAddress[j],
- ip->ipAddress,
- sizeof infoV1->nicList[i].ipAddress[j]);
- infoV1->nicList[i].numIPs++;
- if (infoV1->nicList[i].numIPs == maxIPs) {
- break;
- }
- } else {
- Debug("GuestInfo: ignoring IPV6 address for compatibility.\n");
- }
- }
-
- if (infoV1->nicList[i].numIPs != nic->ips.ips_len) {
- Debug("GuestInfo: some IP addresses were ignored for compatibility.\n");
- }
- if (i == maxNics) {
- break;
- }
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestInfoUpdateVmdb --
- *
- * Update VMDB with new guest information.
- * This is the only function that should need to change when the VMDB pipe
- * is implemented. Since we dont currently have a VMDB instance in the guest
- * the function updates the VMDB instance on the host. Updates are sent only
- * if the values have changed.
- *
- * Result
- * TRUE on success, FALSE on failure.
- *
- * Side-effects
- * VMDB is updated if the given value has changed.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-GuestInfoUpdateVmdb(GuestInfoType infoType, // IN: guest information type
- void *info) // IN: type specific information
-{
- ASSERT(info);
- Debug("Entered update vmdb.\n");
-
- if (vmResumed) {
- vmResumed = FALSE;
- GuestInfoClearCache();
- }
-
- switch (infoType) {
- case INFO_DNS_NAME:
- case INFO_BUILD_NUMBER:
- case INFO_OS_NAME:
- case INFO_OS_NAME_FULL:
- case INFO_UPTIME:
- /*
- * This is one of our key value pairs. Update it if it has changed.
- * Above fall-through is intentional.
- */
-
- if (strcmp(gInfoCache.value[infoType], (char *)info) == 0) {
- /* The value has not changed */
- Debug("Value unchanged for infotype %d.\n", infoType);
- break;
- }
-
- if(!SetGuestInfo(infoType, (char *)info, 0)) {
- Debug("Failed to update key/value pair for type %d.\n", infoType);
- return FALSE;
- }
-
- /* Update the value in the cache as well. */
- Str_Strcpy(gInfoCache.value[infoType], (char *)info, MAX_VALUE_LEN);
- break;
-
- case INFO_IPADDRESS:
- {
- static Bool isCmdV1 = FALSE;
- char *reply = NULL;
- size_t replyLen;
- Bool status;
-
- if (FALSE == isCmdV1) {
- /* 13 = max size of string representation of an int + 3 spaces. */
- char request[sizeof GUEST_INFO_COMMAND + 13];
- GuestNicProto message;
- XDR xdrs;
-
- if (DynXdr_Create(&xdrs) == NULL) {
- return FALSE;
- }
-
- /* Add the RPC preamble: message name, and type. */
- Str_Sprintf(request, sizeof request, "%s %d ",
- GUEST_INFO_COMMAND, INFO_IPADDRESS_V2);
-
- message.ver = NIC_INFO_V2;
- message.GuestNicProto_u.nicsV2 = info;
-
- /* Write preamble and serialized nic info to XDR stream. */
- if (!DynXdr_AppendRaw(&xdrs, request, strlen(request)) ||
- !xdr_GuestNicProto(&xdrs, &message)) {
- Debug("GuestInfo: Error serializing nic info v2 data.");
- DynXdr_Destroy(&xdrs, TRUE);
- return FALSE;
- }
-
- status = RpcOut_SendOneRaw(DynXdr_Get(&xdrs),
- xdr_getpos(&xdrs),
- &reply,
- &replyLen);
- DynXdr_Destroy(&xdrs, TRUE);
- if (status) {
- Debug("GuestInfo: sent nic info message.\n");
- } else {
- Debug("GuestInfo: failed to send V2 nic info message.\n");
- }
-
- if (RpcVMX_ConfigGetBool(FALSE, "printNicInfo")) {
- PrintNicInfo((GuestNicList *) info,
- (int (*)(const char *fmt, ...)) RpcVMX_Log);
- }
- } else {
- status = FALSE;
- }
- if (!status) {
- /*
- * Could be that we are talking to the old protocol that GuestNicInfo is
- * still fixed size. Another try to send the fixed sized Nic info.
- */
- char request[sizeof (GuestNicInfoV1) + sizeof GUEST_INFO_COMMAND +
- 2 + /* 2 bytes are for digits of infotype. */
- 3 * sizeof (char)]; /* 3 spaces */
- GuestNicInfoV1 nicInfo;
-
- free(reply);
- reply = NULL;
-
- Str_Sprintf(request,
- sizeof request,
- "%s %d ",
- GUEST_INFO_COMMAND,
- INFO_IPADDRESS);
- if (GuestInfoConvertNicInfoToNicInfoV1(info, &nicInfo)) {
- memcpy(request + strlen(request),
- &nicInfo,
- sizeof(GuestNicInfoV1));
-
- Debug("GuestInfo: Sending nic info message.\n");
- /* Send all the information in the message. */
- status = RpcOut_SendOneRaw(request,
- sizeof request,
- &reply,
- &replyLen);
-
- Debug("GuestInfo: Just sent fixed sized nic info message.\n");
- if (!status) {
- Debug("Failed to update fixed sized nic information\n");
- free(reply);
- return FALSE;
- }
- isCmdV1 = TRUE;
- } else {
- return FALSE;
- }
- }
-
- Debug("GuestInfo: Updated new NIC information\n");
- free(reply);
- reply = NULL;
- }
- break;
-
- case INFO_MEMORY:
- {
- char request[sizeof(GuestMemInfo) + sizeof GUEST_INFO_COMMAND +
- 2 + /* 2 bytes are for digits of infotype. */
- 3 * sizeof (char)]; /* 3 spaces */
- Bool status;
-
- Debug("GuestInfo: Sending GuestMemInfo message.\n");
- Str_Sprintf(request,
- sizeof request,
- "%s %d ",
- GUEST_INFO_COMMAND,
- INFO_MEMORY);
- memcpy(request + strlen(request),
- info, sizeof(GuestMemInfo));
-
- /* Send all the information in the message. */
- status = RpcOut_SendOneRaw(request, sizeof(request),
- NULL, NULL);
- if (!status) {
- Debug("Error sending GuestMemInfo.\n");
- return FALSE;
- }
- Debug("GuestMemInfo sent successfully.\n");
- break;
- }
-
- case INFO_DISK_FREE_SPACE:
- {
- /*
- * 2 accounts for the digits of infotype and 3 for the three
- * spaces.
- */
- unsigned int requestSize = sizeof GUEST_INFO_COMMAND + 2 + 3 * sizeof (char);
- uint8 partitionCount;
- size_t offset;
- char *request;
- char *reply;
- size_t replyLen;
- Bool status;
- PGuestDiskInfo pdi = (PGuestDiskInfo)info;
- int j = 0;
-
- if (!DiskInfoChanged(pdi)) {
- Debug("GuestInfo: Disk info not changed.\n");
- break;
- }
-
- requestSize += sizeof pdi->numEntries +
- sizeof *pdi->partitionList * pdi->numEntries;
- request = (char *)calloc(requestSize, sizeof (char));
- if (request == NULL) {
- Debug("GuestInfo: Could not allocate memory for request.\n");
- break;
- }
-
- Str_Sprintf(request, requestSize, "%s %d ", GUEST_INFO_COMMAND,
- INFO_DISK_FREE_SPACE);
-
- /* partitionCount is a uint8 and cannot be larger than UCHAR_MAX. */
- if (pdi->numEntries > UCHAR_MAX) {
- Debug("GuestInfo: Too many partitions.\n");
- free(request);
- return FALSE;
- }
- partitionCount = pdi->numEntries;
-
- offset = strlen(request);
-
- /*
- * Construct the disk information message to send to the host. This
- * contains a single byte indicating the number partitions followed by
- * the PartitionEntry structure for each one.
- *
- * Note that the use of a uint8 to specify the partitionCount is the
- * result of a bug (see bug 117224) but should not cause a problem
- * since UCHAR_MAX is 255. Also note that PartitionEntry is packed so
- * it's safe to send it from 64-bit Tools to a 32-bit VMX, etc.
- */
- memcpy(request + offset, &partitionCount, sizeof partitionCount);
- memcpy(request + offset + sizeof partitionCount, pdi->partitionList,
- sizeof *pdi->partitionList * pdi->numEntries);
-
- Debug("sizeof request is %d\n", requestSize);
- status = RpcOut_SendOneRaw(request, requestSize, &reply, &replyLen);
-
- if (!status || (strncmp(reply, "", 1) != 0)) {
- Debug("Failed to update disk information.\n");
- free(request);
- free(reply);
- return FALSE;
- }
-
- Debug("GuestInfo: Updated disk info information\n");
- free(reply);
- free(request);
-
- /* Free any memory previously allocated in the cache. */
- if (gInfoCache.diskInfo.partitionList != NULL) {
- free(gInfoCache.diskInfo.partitionList);
- gInfoCache.diskInfo.partitionList = NULL;
- }
- gInfoCache.diskInfo.numEntries = pdi->numEntries;
- gInfoCache.diskInfo.partitionList = calloc(pdi->numEntries,
- sizeof(PartitionEntry));
- if (gInfoCache.diskInfo.partitionList == NULL) {
- Debug("GuestInfo: could not allocate memory for the disk info cache.\n");
- return FALSE;
- }
-
- for (j = 0; j < pdi->numEntries; j++) {
- gInfoCache.diskInfo.partitionList[j] = pdi->partitionList[j];
- }
- break;
- }
- default:
- Debug("GuestInfo: Invalid info type.\n");
- NOT_REACHED();
- break;
- }
-
- Debug("GuestInfo: Returning after updating guest information\n");
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * SetGuestInfo --
- *
- * Ask Vmx to write some information about the guest into VMDB.
- *
- * Results:
- *
- * TRUE/FALSE depending on whether the RPCI succeeded or failed.
- *
- * Side effects:
- *
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-SetGuestInfo(GuestInfoType key, // IN: the VMDB key to set
- const char *value, // IN:
- char delimiter) // IN: delimiting character for the rpc
- // message. 0 indicates default.
-{
- Bool status;
- char *reply;
- size_t replyLen;
-
- ASSERT(key);
- ASSERT(value);
-
- if (!delimiter) {
- delimiter = GUESTINFO_DEFAULT_DELIMITER;
- }
-
- status = RpcOut_sendOne(&reply, &replyLen, "%s %c%d%c%s", GUEST_INFO_COMMAND,
- delimiter, key, delimiter, value);
-
- if (!status) {
- Debug("SetGuestInfo: Error sending rpc message: %s\n",
- reply ? reply : "NULL");
- free(reply);
- return FALSE;
- }
-
- /* The reply indicates whether the key,value pair was updated in VMDB. */
- status = (strncmp(reply, "", 1) == 0);
- free(reply);
- return status;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestInfoFindMacAddress --
- *
- * Locates a NIC with the given MAC address in the NIC list.
- *
- * Return value:
- * If there is an entry in nicInfo which corresponds to this MAC address,
- * it is returned. If not NULL is returned.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-GuestNic *
-GuestInfoFindMacAddress(GuestNicList *nicInfo, // IN/OUT
- const char *macAddress) // IN
-{
- u_int i;
-
- for (i = 0; i < nicInfo->nics.nics_len; i++) {
- GuestNic *nic = &nicInfo->nics.nics_val[i];
- if (strncmp(nic->macAddress, macAddress, NICINFO_MAC_LEN) == 0) {
- return nic;
- }
- }
-
- return NULL;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * NicInfoChanged --
- *
- * Checks whether Nic information just obtained is different from
- * the information last sent to VMDB.
- *
- * Results:
- *
- * TRUE if the NIC info has changed, FALSE otherwise
- *
- * Side effects:
- *
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-NicInfoChanged(GuestNicList *nicInfo) // IN
-{
- u_int i;
- GuestNicList *cachedNicInfo = &gInfoCache.nicInfo;
-
- if (cachedNicInfo->nics.nics_len != nicInfo->nics.nics_len) {
- Debug("GuestInfo: number of nics has changed\n");
- return TRUE;
- }
-
- for (i = 0; i < cachedNicInfo->nics.nics_len; i++) {
- u_int j;
- GuestNic *cachedNic = &cachedNicInfo->nics.nics_val[i];
- GuestNic *matchedNic;
-
- /* Find the corresponding nic in the new nic info. */
- matchedNic = GuestInfoFindMacAddress(nicInfo, cachedNic->macAddress);
-
- if (NULL == matchedNic) {
- /* This mac address has been deleted. */
- return TRUE;
- }
-
- if (matchedNic->ips.ips_len != cachedNic->ips.ips_len) {
- Debug("GuestInfo: count of ip addresses for mac %d\n",
- matchedNic->ips.ips_len);
- return TRUE;
- }
-
- /* Which IP addresses have been modified for this NIC? */
- for (j = 0; j < cachedNic->ips.ips_len; j++) {
- VmIpAddress *cachedIp = &cachedNic->ips.ips_val[j];
- Bool foundIP = FALSE;
- u_int k;
-
- for (k = 0; k < matchedNic->ips.ips_len; k++) {
- VmIpAddress *matchedIp = &matchedNic->ips.ips_val[k];
- if (0 == strncmp(cachedIp->ipAddress,
- matchedIp->ipAddress,
- NICINFO_MAX_IP_LEN)) {
- foundIP = TRUE;
- break;
- }
- }
-
- if (FALSE == foundIP) {
- /* This ip address couldn't be found and has been modified. */
- Debug("GuestInfo: mac address %s, ipaddress %s deleted\n",
- cachedNic->macAddress,
- cachedIp->ipAddress);
- return TRUE;
- }
-
- }
-
- }
-
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * PrintNicInfo --
- *
- * Print NIC info struct using the specified print function.
- *
- * Results:
- * Sum of return values of print function (for printf, this will be the
- * number of characters printed).
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-PrintNicInfo(GuestNicList *nicInfo, // IN
- int (*PrintFunc)(const char *, ...)) // IN
-{
- int ret = 0;
- u_int i = 0;
-
- ret += PrintFunc("NicInfo: count: %ud\n", nicInfo->nics.nics_len);
- for (i = 0; i < nicInfo->nics.nics_len; i++) {
- u_int j;
- GuestNic *nic = &nicInfo->nics.nics_val[i];
-
- ret += PrintFunc("NicInfo: nic [%d/%d] mac: %s",
- i+1,
- nicInfo->nics.nics_len,
- nic->macAddress);
-
- for (j = 0; j < nic->ips.ips_len; j++) {
- VmIpAddress *ipAddress = &nic->ips.ips_val[j];
-
- ret += PrintFunc("NicInfo: nic [%d/%d] IP [%d/%d]: %s",
- i+1,
- nicInfo->nics.nics_len,
- j+1,
- nic->ips.ips_len,
- ipAddress->ipAddress);
- }
- }
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * DiskInfoChanged --
- *
- * Checks whether disk info information just obtained is different from
- * the information last sent to VMDB.
- *
- * Results:
- *
- * TRUE if the disk info has changed, FALSE otherwise.
- *
- * Side effects:
- *
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-DiskInfoChanged(PGuestDiskInfo diskInfo) // IN:
-{
- int index;
- char *name;
- int i;
- int matchedPartition;
- PGuestDiskInfo cachedDiskInfo;
-
- cachedDiskInfo = &gInfoCache.diskInfo;
-
- if (cachedDiskInfo->numEntries != diskInfo->numEntries) {
- Debug("GuestInfo: number of disks has changed\n");
- return TRUE;
- }
-
- /* Have any disks been modified? */
- for (index = 0; index < cachedDiskInfo->numEntries; index++) {
- name = cachedDiskInfo->partitionList[index].name;
-
- /* Find the corresponding partition in the new partition info. */
- for (i = 0; i < diskInfo->numEntries; i++) {
- if (!strncmp(diskInfo->partitionList[i].name, name, PARTITION_NAME_SIZE)) {
- break;
- }
- }
-
- matchedPartition = i;
- if (matchedPartition == diskInfo->numEntries) {
- /* This partition has been deleted. */
- Debug("GuestInfo: partition %s deleted\n", name);
- return TRUE;
- } else {
- /* Compare the free space. */
- if (diskInfo->partitionList[matchedPartition].freeBytes !=
- cachedDiskInfo->partitionList[index].freeBytes) {
- Debug("GuestInfo: free space changed\n");
- return TRUE;
- }
- if (diskInfo->partitionList[matchedPartition].totalBytes !=
- cachedDiskInfo->partitionList[index].totalBytes) {
- Debug("GuestInfo: total space changed\n");
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestInfoClearCache --
- *
- * Clears the cached guest info data.
- *
- * Results:
- * None.
- *
- * Side effects:
- * gInfoCache is cleared.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-GuestInfoClearCache(void)
-{
- int i;
-
- for (i = 0; i < INFO_MAX; i++) {
- gInfoCache.value[i][0] = 0;
- }
-
- VMX_XDR_FREE(xdr_GuestNicList, &gInfoCache.nicInfo);
- memset(&gInfoCache.nicInfo, 0, sizeof gInfoCache.nicInfo);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestInfoServer_SendUptime --
- *
- * Set the guest uptime through the backdoor.
- *
- * Results:
- * TRUE if the rpci send succeeded
- * FALSE if it failed
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-GuestInfoServer_SendUptime(void)
-{
- char *uptime = Str_Asprintf(NULL, "%"FMT64"u", System_Uptime());
- Bool ret;
-
- ASSERT_MEM_ALLOC(uptime);
- Debug("Setting guest uptime to '%s'\n", uptime);
- ret = GuestInfoUpdateVmdb(INFO_UPTIME, uptime);
- free(uptime);
- return ret;
-}
-
noinst_LTLIBRARIES = libGuestRpc.la
libGuestRpc_la_SOURCES =
+libGuestRpc_la_SOURCES += cpFileContents_xdr.c
libGuestRpc_la_SOURCES += ghiGetBinaryHandlers_xdr.c
libGuestRpc_la_SOURCES += ghiProtocolHandler_xdr.c
libGuestRpc_la_SOURCES += guestlibV3_xdr.c
CFLAGS += -Wno-unused
CLEANFILES =
+CLEANFILES += cpFileContents.h
+CLEANFILES += cpFileContents_xdr.c
CLEANFILES += ghiGetBinaryHandlers.h
CLEANFILES += ghiGetBinaryHandlers_xdr.c
CLEANFILES += ghiProtocolHandler.h
CLEANFILES += unityActive_xdr.c
EXTRA_DIST =
+EXTRA_DIST += cpFileContents.x
EXTRA_DIST += ghiGetBinaryHandlers.x
EXTRA_DIST += ghiProtocolHandler.x
EXTRA_DIST += guestlibV3.x
# files if not invoked in the same directory as the source file, so we need
# to copy the sources to the build dir before compiling them.
+cpFileContents.h: cpFileContents.x
+ if [ $(top_builddir) != $(top_srcdir) ]; then \
+ cp -f $(top_srcdir)/lib/guestRpc/cpFileContents.x $(builddir); \
+ fi
+ $(RPCGEN) $(RPCGENFLAGS) -h -o $@ $(builddir)/cpFileContents.x
+ $(SED) 's,rpc/rpc\.h,vmxrpc.h,' $@ > $@.tmp
+ mv $@.tmp $@
+ $(MKDIR_P) $(top_builddir)/lib/include/guestrpc
+ cp $@ $(top_builddir)/lib/include/guestrpc
+
+cpFileContents_xdr.c: cpFileContents.x cpFileContents.h
+ $(RPCGEN) $(RPCGENFLAGS) -c -o $@ $(builddir)/cpFileContents.x
+
ghiGetBinaryHandlers.h: ghiGetBinaryHandlers.x
if [ $(top_builddir) != $(top_srcdir) ]; then \
cp -f $(top_srcdir)/lib/guestRpc/ghiGetBinaryHandlers.x $(builddir); \
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2008 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * cpFileContents.x --
+ *
+ * Definition of the data structures used in the GuestRpc commands to
+ * provide information about file contents for cross platform clipboard.
+ */
+
+/*
+ * Enumerates the different versions of the messages.
+ */
+enum CPFileContentsVersion {
+ CP_FILE_CONTENTS_V1 = 1
+};
+
+struct CPFileItem {
+ uint64 validFlags; /* Valid members. */
+ uint32 type; /* File type */
+ uint64 size; /* File size (in bytes) */
+ uint64 createTime; /* Creation time. Ignored by POSIX */
+ uint64 accessTime; /* Time of last access */
+ uint64 writeTime; /* Time of last write */
+ uint64 attrChangeTime; /* Time file attributess were last
+ * changed. Ignored by Windows */
+ uint64 permissions; /* Permissions bits */
+ uint64 attributes; /* File attributes. */
+ opaque cpName<>; /* File name in cross-platform format. */
+ opaque content<>; /* File contents. */
+};
+
+struct CPFileContentsList {
+ uint64 totalFileSize;
+ struct CPFileItem fileItem<>;
+};
+
+/*
+ * This defines the protocol for cross-platform file contents format. The union
+ * allows us to create new versions of the protocol later by creating new values
+ * in the CPFileContentsVersion enumeration, without having to change much of
+ * the code calling the (de)serialization functions.
+ *
+ * Since the union doesn't have a default case, de-serialization will fail
+ * if an unknown version is provided on the wire.
+ */
+union CPFileContents switch (CPFileContentsVersion ver) {
+case CP_FILE_CONTENTS_V1:
+ struct CPFileContentsList *fileContentsV1;
+};
+
static void
HgfsServerSigOplockBreak(int sigNum, // IN: Signal number
siginfo_t *info, // IN: Additional info about signal
+ ucontext_t *u, // IN: Interrupted context (regs etc)
void *clientData) // IN: Ignored
{
ServerLockData *lockData;
#define BUILD_NUMBER \
- "build-154848"
+ "build-162451"
#define BUILD_NUMBER_NUMERIC \
- 154848
+ 162451
#define BUILD_NUMBER_NUMERIC_STRING \
- "154848"
+ "162451"
#define PRODUCT_BUILD_NUMBER \
- "product-build-495"
+ "product-build-531"
#define PRODUCT_BUILD_NUMBER_NUMERIC \
- 495
+ 531
#define PRODUCT_BUILD_NUMBER_NUMERIC_STRING \
- "495"
+ "531"
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
# define CONFVAL_RESUMESCRIPT_DEFAULT "RESUME.NCF"
# define CONFVAL_SUSPENDSCRIPT_DEFAULT "SUSPEND.NCF"
#elif ! defined(_WIN32)
-# define CONFNAME_HALT "halt-command"
-# define CONFNAME_REBOOT "reboot-command"
-# ifdef sun
-# define CONFVAL_HALT_DEFAULT "/usr/sbin/init 5"
-# define CONFVAL_REBOOT_DEFAULT "/usr/sbin/init 6"
-# else
-# define CONFVAL_HALT_DEFAULT "/sbin/shutdown -h now"
-# define CONFVAL_REBOOT_DEFAULT "/sbin/shutdown -r now"
-# endif
-
# define CONFVAL_POWERONSCRIPT_DEFAULT "poweron-vm-default"
# define CONFVAL_POWEROFFSCRIPT_DEFAULT "poweroff-vm-default"
# define CONFVAL_RESUMESCRIPT_DEFAULT "resume-vm-default"
# define CONFVAL_SUSPENDSCRIPT_DEFAULT "suspend-vm-default"
-
-# define CONFNAME_MOUNT_POINT "mount-point"
-# define CONFVAL_MOUNT_POINT_DEFAULT "/hgfs"
#else
# define CONFVAL_POWERONSCRIPT_DEFAULT "poweron-vm-default.bat"
# define CONFVAL_POWEROFFSCRIPT_DEFAULT "poweroff-vm-default.bat"
DND_TRANSPORT_PACKET_HEADER_SIZE)
#define DND_MAX_TRANSPORT_LATENCY_TIME 3 * 1000000 /* 3 seconds. */
+/*
+ * Structure to access methods of currently used blocking mechanism.
+ */
+typedef struct DnDBlockControl {
+ int fd;
+ const char *blockRoot;
+ Bool (*AddBlock)(int blockFd, const char *blockPath);
+ Bool (*RemoveBlock)(int blockFd, const char *blockedPath);
+} DnDBlockControl;
+
#ifdef _WIN32
/*
* Windows-specific functions
Unicode DnD_GetLastDirName(const char *str);
/* vmblock support functions. */
-int DnD_InitializeBlocking(void);
-Bool DnD_UninitializeBlocking(int blockFd);
-Bool DnD_AddBlock(int blockFd, const char *blockPath);
-Bool DnD_RemoveBlock(int blockFd, const char *blockedPath);
+Bool DnD_InitializeBlocking(DnDBlockControl *blkCtrl);
+Bool DnD_UninitializeBlocking(DnDBlockControl *blkCtrl);
+Bool DnD_CompleteBlockInitialization(int fd, DnDBlockControl *blkCtrl);
+
+static INLINE Bool
+DnD_BlockIsReady(DnDBlockControl *blkCtrl) // IN: blocking control structure
+{
+ if (blkCtrl->fd >= 0) {
+ ASSERT(blkCtrl->AddBlock && blkCtrl->RemoveBlock);
+ return TRUE;
+ }
+ return FALSE;
+}
/* Transport layer big buffer support functions. */
void DnD_TransportBufInit(DnDTransportBuffer *buf,
HGFSU_CAP_DESKTOP_SHORTCUT = 12, // supports creating HGFS link on GOS Desktop
HGFSU_CAP_MAP_DRIVE = 13, // supports mapping a GOS drive letter to HGFS
GHI_CAP_SET_HANDLER = 14, // supports setting the handler for types/protocols
- UNITY_CAP_STATUS_UNITY_ACTIVE = 15, // supports GuestRpc bits for Unity Status
+ UNITY_CAP_STATUS_UNITY_ACTIVE = 15, // supports GuestRpc bits for Unity Status
+ GHI_CAP_SET_OUTLOOK_TEMP_FOLDER = 16 // supports setting the Outlook temp folder
} GuestCapabilities;
typedef struct {
*/
/*
- * This table must be sorted such that it can be indexed using the
+ * This table must be sorted such that it can be indexed using the
* GuestCapabilities enum above. RPC calls pass the value, and the
- * handler code uses it as an index. In other words, the value of the
+ * handler code uses it as an index. In other words, the value of the
* caps field at index i must be equal to i as well. This is because
* the code that looks up entries in this table assume as much. It
* also means we don't need the cap field, or, to justify its existence,
{ HGFSU_CAP_MAP_DRIVE, HGFSU_CAP_VMDB_PATH, "mapDrive" },
{ GHI_CAP_SET_HANDLER, GHI_CAP_VMDB_PATH, "setHandler" },
{ UNITY_CAP_STATUS_UNITY_ACTIVE, UNITY_CAP_VMDB_PATH, "unityActive" },
+ { GHI_CAP_SET_OUTLOOK_TEMP_FOLDER, GHI_CAP_VMDB_PATH, "setOutlookTempFolder" }
};
#endif // VM_NEED_VMDB_GUEST_CAP_MAPPING
#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_VMCORE
+#define INCLUDE_ALLOW_VMKERNEL
#include "includeCheck.h"
#include "vm_basic_types.h"
#define LOG_DEFAULT_KEEPOLD 3
#endif
+#define LOG_NO_BPS_LIMIT 0xFFFFFFFF
+
#ifdef VMX86_RELEASE
#define LOG_DEFAULT_THROTTLE_BPS 1000
#else
-#define LOG_DEFAULT_THROTTLE_BPS 0
+#define LOG_DEFAULT_THROTTLE_BPS LOG_NO_BPS_LIMIT
#endif
#define LOG_DEFAULT_THROTTLE_THRESHOLD 1000000
LOGLEVEL_VAR(objc), /* lib/objc */ \
LOGLEVEL_VAR(blit), /* lib/blit */ \
LOGLEVEL_VAR(vmnetBridge), \
+ LOGLEVEL_VAR(wifi), /* macWireless and wpa_supplicant */
LOGLEVEL_EXTENSION_DECLARE(LOGLEVEL_USER);
Bool (*lazyProgress)(void *handle,
const char *msgID,
const char *message,
+ Bool allowCancel,
int percent);
void (*lazyProgressEnd)(void *handle);
...)
PRINTF_DECL(2, 3);
EXTERN Bool Msg_LazyProgress(void *handle,
+ Bool allowCancel,
int percent,
const char *idFmt,
...)
- PRINTF_DECL(3, 4);
+ PRINTF_DECL(4, 5);
EXTERN void Msg_LazyProgressEnd(void *handle);
typedef Bool (*RpcChannelStartFn)(struct RpcChannel *);
-typedef Bool (*RpcChannelStopFn)(struct RpcChannel *);
-typedef Bool (*RpcChannelShutdownFn)(struct RpcChannel *);
+typedef void (*RpcChannelStopFn)(struct RpcChannel *);
+typedef void (*RpcChannelShutdownFn)(struct RpcChannel *);
typedef Bool (*RpcChannelSendFn)(struct RpcChannel *,
char *data,
size_t dataLen,
*/
#if !defined(_WIN32) && !defined(N_PLAT_NLM)
Bool System_WritePidFile(const char *fileName, pid_t pid);
-Bool System_Daemon(Bool nochdir, Bool noclose, const char *pidFile);
const char **System_GetNativeEnviron(const char **compatEnviron);
void System_FreeNativeEnviron(const char **nativeEnviron);
int System_UnsetEnv(const char *variableName);
#define UNITY_RPC_SHOW_TASKBAR "unity.show.taskbar"
#define UNITY_RPC_WINDOW_MOVE_RESIZE "unity.window.move_resize"
#define UNITY_RPC_DESKTOP_WORK_AREA_SET "unity.desktop.work_area.set"
+#define UNITY_RPC_WINDOW_SHOW "unity.window.show"
+#define UNITY_RPC_WINDOW_HIDE "unity.window.hide"
#define UNITY_RPC_WINDOW_MINIMIZE "unity.window.minimize"
#define UNITY_RPC_WINDOW_UNMINIMIZE "unity.window.restore"
#define UNITY_RPC_WINDOW_MAXIMIZE "unity.window.maximize"
#define GHI_RPC_SET_GUEST_HANDLER "ghi.guest.handler.set"
#define GHI_RPC_RESTORE_DEFAULT_GUEST_HANDLER "ghi.guest.handler.restoreDefault"
#define GHI_RPC_OUTLOOK_SET_TEMP_FOLDER "ghi.guest.outlook.set.tempFolder"
+#define GHI_RPC_OUTLOOK_RESTORE_TEMP_FOLDER "ghi.guest.outlook.restore.tempFolder"
+#define GHI_RPC_TRASH_FOLDER_ACTION "ghi.guest.trashFolder.action"
+#define GHI_RPC_TRASH_FOLDER_GET_ICON "ghi.guest.trashFolder.getIcon"
/* @} */
#define UNITY_RPC_SHOW_TASKBAR_CAP "tools.capability.unity.taskbar"
#define GHI_RPC_LAUNCHMENU_CHANGE "tools.ghi.launchmenu.change"
#define GHI_RPC_PROTOCOL_HANDLER_INFO "tools.ghi.protocolhandler.info"
+#define GHI_RPC_TRASH_FOLDER_STATE "ghi.guest.trashFolder.state"
#define UNITY_RPC_UNITY_ACTIVE "unity.active"
#define GHI_RPC_HOST_SHELL_ACTION "ghi.host.shell.action"
* @li @ref UNITY_START_MENU_RESOLVED_LAUNCH_FOLDER is the same contents as
* @ref UNITY_START_MENU_LAUNCH_FOLDER however each item that is a shortcut
* (link) is resolved into its destination path.
+ *
+ * @li @ref UNITY_START_MENU_RECENT_DOCUMENTS_FOLDER is the list of recently
+ * used documents for the guest.
*/
-#define UNITY_START_MENU_LAUNCH_FOLDER "VMGuestLaunchItems"
-#define UNITY_START_MENU_FIXED_FOLDER "VMGuestFixedItems"
-#define UNITY_START_MENU_ALL_HANDLERS_FOLDER "VMGuestAllHandlers"
-#define UNITY_START_MENU_RESOLVED_LAUNCH_FOLDER "VMGuestResolvedItems"
+#define UNITY_START_MENU_LAUNCH_FOLDER "VMGuestLaunchItems"
+#define UNITY_START_MENU_FIXED_FOLDER "VMGuestFixedItems"
+#define UNITY_START_MENU_ALL_HANDLERS_FOLDER "VMGuestAllHandlers"
+#define UNITY_START_MENU_RESOLVED_LAUNCH_FOLDER "VMGuestResolvedItems"
+#define UNITY_START_MENU_RECENT_DOCUMENTS_FOLDER "VMGuestRecentDocuments"
/* @} */
@endverbatim
+ @def UNITY_RPC_WINDOW_SHOW
+ @brief Make the specified window visible.
+ @code
+ UNITY_RPC_WINDOW_SHOW UnityWindowId
+ @endcode
+ @param[in] UnityWindowId UnityWindowId of window to show
+
+
+ @def UNITY_RPC_WINDOW_HIDE
+ @brief Hide the specified window.
+ @code
+ UNITY_RPC_WINDOW_HIDE UnityWindowId
+ @endcode
+ @param[in] UnityWindowId UnityWindowId of window to hide
+
+
@def UNITY_RPC_WINDOW_MINIMIZE
@brief Minimize the specified window.
@code
VIX_E_WRAPPER_WORKSTATION_NOT_INSTALLED = 22001,
VIX_E_WRAPPER_VERSION_NOT_FOUND = 22002,
VIX_E_WRAPPER_SERVICEPROVIDER_NOT_FOUND = 22003,
+ VIX_E_WRAPPER_PLAYER_NOT_INSTALLED = 22004,
};
// {{ End VIX_ERROR }}
VIX_SERVICEPROVIDER_DEFAULT = 1,
VIX_SERVICEPROVIDER_VMWARE_SERVER = 2,
VIX_SERVICEPROVIDER_VMWARE_WORKSTATION = 3,
+ VIX_SERVICEPROVIDER_VMWARE_PLAYER = 4,
VIX_SERVICEPROVIDER_VMWARE_VI_SERVER = 10,
};
void *clientData);
/*
- * This is the state of an individual VM.
+ * This is the state of an individual VM. These values are bitwise flags.
+ * The actual value returned for may be a bitwise OR of one more of these
+ * flags, along with other reserved values not documented here.
*/
typedef int VixPowerState;
VixMsgSetSnapshotInfoResponse;
+/*
+ * Rolling Tier operations.
+ */
+typedef
+#include "vmware_pack_begin.h"
+struct VixMsgAddRollingTierRequest {
+ VixCommandRequestHeader header;
+ int32 options;
+ uint32 interval;
+ int maximum;
+ uint32 clientFlags;
+ uint32 propertyListLength;
+ /*
+ * Followed by:
+ * serialized property list.
+ */
+}
+#include "vmware_pack_end.h"
+VixMsgAddRollingTierRequest;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VixMsgAddRollingTierResponse {
+ VixCommandResponseHeader header;
+ uint32 tierUid;
+ uint32 propertyListLength;
+ /*
+ * Followed by:
+ * serialized property list.
+ */
+}
+#include "vmware_pack_end.h"
+VixMsgAddRollingTierResponse;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VixMsgRemoveRollingTierRequest {
+ VixCommandRequestHeader header;
+
+ int32 options;
+ int32 tierUid;
+ uint32 propertyListLength;
+ /*
+ * Followed by:
+ * serialized property list.
+ */
+}
+#include "vmware_pack_end.h"
+VixMsgRemoveRollingTierRequest;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VixMsgRemoveRollingTierResponse {
+ VixCommandResponseHeader header;
+ uint32 propertyListLength;
+ /*
+ * Followed by:
+ * serialized property list.
+ */
+}
+#include "vmware_pack_end.h"
+VixMsgRemoveRollingTierResponse;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VixMsgListRollingTierRequest {
+ VixCommandRequestHeader header;
+
+ int32 options;
+ uint32 propertyListLength;
+ /*
+ * Followed by:
+ * serialized property list.
+ */
+}
+#include "vmware_pack_end.h"
+VixMsgListRollingTierRequest;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VixMsgListRollingTierResponse {
+ VixCommandResponseHeader header;
+ uint32 propertyListLength;
+ /*
+ * Followed by:
+ * serialized property list.
+ */
+}
+#include "vmware_pack_end.h"
+VixMsgListRollingTierResponse;
+
+
/*
* Fork a running VM.
*/
VIX_COMMAND_TRANSFER_REQUEST = 161,
VIX_COMMAND_TRANSFER_FINAL_DATA = 162,
- VIX_COMMAND_LAST_NORMAL_COMMAND = 163,
+ VIX_COMMAND_ADD_ROLLING_SNAPSHOT_TIER = 163,
+ VIX_COMMAND_REMOVE_ROLLING_SNAPSHOT_TIER = 164,
+ VIX_COMMAND_LIST_ROLLING_SNAPSHOT_TIER = 165,
+
+ VIX_COMMAND_ADD_ROLLING_SNAPSHOT_TIER_VMX = 166,
+ VIX_COMMAND_REMOVE_ROLLING_SNAPSHOT_TIER_VMX = 167,
+ VIX_COMMAND_LIST_ROLLING_SNAPSHOT_TIER_VMX = 168,
+
+ VIX_COMMAND_LAST_NORMAL_COMMAND = 169,
VIX_TEST_UNSUPPORTED_TOOLS_OPCODE_COMMAND = 998,
VIX_TEST_UNSUPPORTED_VMX_OPCODE_COMMAND = 999,
const char *buffer,
size_t bufferSize);
+VixError VixPropertyList_DeserializeNoClobber(VixPropertyListImpl *propListImpl,
+ const char *buffer,
+ size_t bufferSize);
+
VixError VixPropertyList_GetString(struct VixPropertyListImpl *propList,
int propertyID,
int index,
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * vmBackup.h --
- *
- * Declaration of functions shared by the vmBackup implementations (both
- * VSS and non-VSS).
- */
-
-#ifndef _VMBACKUP_H_
-#define _VMBACKUP_H_
-
-#include "vm_basic_types.h"
-#include "vm_assert.h"
-#include "vmbackup_def.h"
-
-#include "dbllnklst.h"
-#include "eventManager.h"
-#include "rpcin.h"
-#include "str.h"
-
-typedef enum {
- VMBACKUP_STATUS_PENDING,
- VMBACKUP_STATUS_FINISHED,
- VMBACKUP_STATUS_CANCELED,
- VMBACKUP_STATUS_ERROR
-} VmBackupOpStatus;
-
-
-/*
- * This is a "base struct" for asynchronous operations monitored by the
- * state machine. Each implementation should provide these three functions
- * at the start of the struct so that the state machine can properly
- * interact with it.
- */
-
-typedef struct VmBackupOp {
- VmBackupOpStatus (*queryFn)(struct VmBackupOp *);
- void (*releaseFn)(struct VmBackupOp *);
- void (*cancelFn)(struct VmBackupOp *);
-} VmBackupOp;
-
-
-/*
- * Holds information about the current state of the backup operation.
- * Don't modify the fields directly - rather, use VmBackup_SetCurrentOp,
- * which does most of the handling needed by users of the state machine.
- *
- * The "SendEvent" function is a pointer so that the VSS code, which
- * is linked against a different runtime, can call it and be able to
- * reuse the keep alive functionality without having to link to the
- * vmBackup library.
- */
-
-typedef struct VmBackupState {
- Bool (*SendEvent)(const char *, const uint32, const char *);
- VmBackupOp *currentOp;
- const char *currentOpName;
- char *volumes;
- uint32 pollPeriod;
- Event *timerEvent;
- Event *keepAlive;
- Bool (*callback)(struct VmBackupState *);
- Bool syncProviderRunning;
- Bool forceRequeue;
- Bool snapshotDone;
- Bool syncProviderFailed;
- Bool generateManifests;
- Bool clientAborted;
- intptr_t clientData;
- void *scripts;
- const char *configDir;
- ssize_t currentScript;
- Bool loggingEnabled;
-} VmBackupState;
-
-typedef Bool (*VmBackupCallback)(VmBackupState *);
-typedef Bool (*VmBackupProviderCallback)(VmBackupState *, void *clientData);
-
-
-/*
- * Defines the interface between the state machine and the implementation
- * of the "sync provider": either the VSS requestor or the sync driver
- * provider, currently.
- */
-
-typedef struct VmBackupSyncProvider {
- VmBackupProviderCallback start;
- VmBackupProviderCallback abort;
- VmBackupProviderCallback snapshotDone;
- void (*release)(struct VmBackupSyncProvider *);
- void *clientData;
-} VmBackupSyncProvider;
-
-
-/* Functions to start / stop the backup state machine. */
-
-
-Bool VmBackup_Init(RpcIn *rpcin,
- DblLnkLst_Links *eventQueue,
- VmBackupSyncProvider *provider,
- Bool loggingEnabled);
-
-void VmBackup_Shutdown(RpcIn *rpcin);
-
-VmBackupSyncProvider *VmBackup_NewSyncDriverProvider(void);
-
-
-/*
- * Macro that checks if the given string matches the given event. Used
- * by the test code to check the events sent to the VMX.
- */
-#define VmBackup_IsEvent(str, evt) \
- (Str_Strncmp((str), (evt), (sizeof (evt)) - 1) == 0)
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackup_SetCurrentOp --
- *
- * Sets the current asynchronous operation being monitored, and an
- * optional callback for after it's done executing. If the operation
- * is NULL, the callback is set to execute later (currently, later = 200ms).
- *
- * Result
- * FALSE if the given operation is NULL.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-INLINE static Bool
-VmBackup_SetCurrentOp(VmBackupState *state,
- VmBackupOp *op,
- VmBackupCallback callback,
- const char *currentOpName)
-{
- ASSERT(state != NULL);
- ASSERT(state->currentOp == NULL);
- state->currentOp = op;
- state->callback = callback;
- state->currentOpName = currentOpName;
- state->forceRequeue = (callback != NULL && state->currentOp == NULL);
- return (op != NULL);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackup_QueryStatus --
- *
- * Convenience function to call the operation-specific query function.
- *
- * Result
- * A VmBackupOpStatus value.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-INLINE static VmBackupOpStatus
-VmBackup_QueryStatus(VmBackupOp *op) // IN
-{
- ASSERT(op != NULL);
- return op->queryFn(op);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackup_Cancel --
- *
- * Convenience function to call the operation-specific cancel function.
- * Code calling this function should still call VmBackup_QueryStatus()
- * waiting for it to return a finished status (i.e., something other
- * than VMBACKUP_STATUS_PENDING).
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-INLINE static void
-VmBackup_Cancel(VmBackupOp *op) // IN
-{
- ASSERT(op != NULL);
- op->cancelFn(op);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackup_Release --
- *
- * Convenience function to call the operation-specific release function.
- * Releasing a state object that hasn't finished yet (i.e.,
- * VmBackup_QueryStatus returns VMBACKUP_STATUS_PENDING) can result in
- * undefined behavior.
- *
- * Result
- * None.
- *
- * Side effects:
- * Operation pointer is not valid anymore.
- *
- *-----------------------------------------------------------------------------
- */
-
-INLINE static void
-VmBackup_Release(VmBackupOp *op) // IN
-{
- ASSERT(op != NULL);
- op->releaseFn(op);
-}
-
-#endif
-
#elif defined(__APPLE__) && defined(KERNEL)
+#include "availabilityMacOS.h"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// The Mac OS 10.5 kernel SDK defines va_copy in stdarg.h.
+#include <stdarg.h>
+#else
/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
+ * The Mac OS 10.4 kernel SDK needs va_copy. Based on inspection of
+ * stdarg.h from the MacOSX10.4u.sdk kernel framework, this should
+ * work.
*/
-
#define va_copy(dest, src) ((dest) = (src))
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#elif defined(__GNUC__) && (__GNUC__ < 3)
* Copyright (C) 2008 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
+#define PCI_DEVICE_ID_VMWARE_VMXWIFI 0x07B8
#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
/* The hypervisor device might grow. Please leave room
#define PLAYER_VERSION "e.x.p"
#define V2V_VERSION "e.x.p"
#define V2V_FILE_VERSION 1,0,0,0
-#define FUSION_VERSION "2.0"
+#define FUSION_VERSION "3.0"
// These must match VIE_FILEVERSION above
#define SYSIMAGE_VERSION "4.0.0"
/*
* The current Tools version, derived from vm_tools_version.h. Do not modify this.
*/
-#define TOOLS_VERSION "2009.03.18"
+#define TOOLS_VERSION "2009.04.23"
#ifdef VMX86_VPX
#define VIM_API_TYPE "VirtualCenter"
# include <sys/param.h>
#endif
-#define VMBLOCK_FS_NAME "vmblock"
+
+/*
+ * FUSE definitions. They are supposed to be used by userspace code and
+ * therefore not guarded by ARCH defines since FUSE can potentially
+ * be used on different operating systems.
+ */
+
+#define VMBLOCK_FUSE_ADD_FILEBLOCK 'a'
+#define VMBLOCK_FUSE_DEL_FILEBLOCK 'd'
+#ifdef VMX86_DEVEL
+# define VMBLOCK_FUSE_LIST_FILEBLOCKS 'l'
+#endif /* VMX86_DEVEL */
+
+/*
+ * If you try 'read'-ing from file descriptor vmblock-fuse is supposed
+ * to respond with the following. It is used to check whether we deal
+ * with FUSE or in-kernel implementation.
+ */
+#define VMBLOCK_FUSE_READ_RESPONSE "I am VMBLOCK-FUSE"
+
+#define VMBLOCK_FUSE_FS_NAME "fuse.vmware-vmblock"
+#define VMBLOCK_FUSE_MOUNT_POINT "/tmp/vmblock-fuse"
+#define VMBLOCK_FUSE_CTRL_MNTPNT "blockdir"
+#define VMBLOCK_FUSE_FS_ROOT VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_CTRL_MNTPNT
+#define VMBLOCK_FUSE_DEVICE_NAME "dev"
+#define VMBLOCK_FUSE_DEVICE VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_DEVICE_NAME
+#define VMBLOCK_FUSE_DEVICE_MODE O_RDWR
/* Commands for the control half of vmblock driver */
#if defined(vmblock_fuse)
+/* These definitions are for vmblock-fuse module itself */
# include <unistd.h>
# include <limits.h>
# include <string.h>
# include <errno.h>
# include "vm_basic_types.h"
-# define VMBLOCK_ADD_FILEBLOCK 'a'
-# define VMBLOCK_DEL_FILEBLOCK 'd'
+# define VMBLOCK_ADD_FILEBLOCK VMBLOCK_FUSE_ADD_FILEBLOCK
+# define VMBLOCK_DEL_FILEBLOCK VMBLOCK_FUSE_DEL_FILEBLOCK
# ifdef VMX86_DEVEL
-# define VMBLOCK_LIST_FILEBLOCKS 'l'
+# define VMBLOCK_LIST_FILEBLOCKS VMBLOCK_FUSE_LIST_FILEBLOCKS
# endif /* VMX86_DEVEL */
/*
* Some of the following names don't actually make much sense on their own.
* They're used for consistency with the other ports. See the file header for
* explanations of what they're used for.
*/
-# define VMBLOCK_DEVICE_NAME "dev"
-# define VMBLOCK_CONTROL_MOUNTPOINT "blockdir"
-# define VMBLOCK_DEVICE "/tmp/vmblock/" VMBLOCK_DEVICE_NAME
-# define VMBLOCK_DEVICE_MODE O_WRONLY
-# define VMBLOCK_MOUNT_POINT "/tmp/vmblock/" VMBLOCK_CONTROL_MOUNTPOINT
-static INLINE ssize_t
- VMBLOCK_CONTROL(int fd, char op, const char *path)
-{
- /*
- * buffer needs room for an operation character and a string with max length
- * PATH_MAX - 1.
- */
-
- char buffer[PATH_MAX];
- size_t pathLength;
-
- pathLength = strlen(path);
- if (pathLength >= PATH_MAX) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- buffer[0] = op;
- memcpy(buffer + 1, path, pathLength);
-
- /*
- * The lseek is only to prevent the file pointer from overflowing;
- * vmblock-fuse ignores the file pointer / offset. Overflowing the file
- * pointer causes write to fail:
- * http://article.gmane.org/gmane.comp.file-systems.fuse.devel/6648
- * There's also a race condition here where many threads all calling
- * VMBLOCK_CONTROL at the same time could have all their seeks executed one
- * after the other, followed by all the writes. Again, it's not a problem
- * unless the file pointer overflows which is very unlikely with 32 bit
- * offsets and practically impossible with 64 bit offsets.
- */
-
- if (lseek(fd, 0, SEEK_SET) < 0) {
- return -1;
- }
- if (write(fd, buffer, pathLength + 1) < 0) {
- return -1;
- }
- return 0;
-}
+# define VMBLOCK_FS_NAME VMBLOCK_FUSE_FS_NAME
+# define VMBLOCK_DEVICE_NAME VMBLOCK_FUSE_DEVICE_NAME
+# define VMBLOCK_CONTROL_MOUNTPOINT VMBLOCK_FUSE_CTRL_MNTPNT
+# define VMBLOCK_DEVICE VMBLOCK_FUSE_DEVICE
+# define VMBLOCK_DEVICE_MODE VMBLOCK_FUSE_DEVICE_MODE
+# define VMBLOCK_MOUNT_POINT VMBLOCK_FUSE_MOUNT_POINT
#elif defined(linux)
-# define VMBLOCK_ADD_FILEBLOCK 98
-# define VMBLOCK_DEL_FILEBLOCK 99
+# define VMBLOCK_ADD_FILEBLOCK 98
+# define VMBLOCK_DEL_FILEBLOCK 99
# ifdef VMX86_DEVEL
-# define VMBLOCK_LIST_FILEBLOCKS 100
+# define VMBLOCK_LIST_FILEBLOCKS 100
# endif
-# define VMBLOCK_CONTROL_DIRNAME VMBLOCK_FS_NAME
-# define VMBLOCK_CONTROL_DEVNAME "dev"
-# define VMBLOCK_CONTROL_MOUNTPOINT "mountPoint"
-# define VMBLOCK_CONTROL_PROC_DIRNAME "fs/" VMBLOCK_CONTROL_DIRNAME
+# define VMBLOCK_FS_NAME "vmblock"
+# define VMBLOCK_CONTROL_DIRNAME VMBLOCK_FS_NAME
+# define VMBLOCK_CONTROL_DEVNAME "dev"
+# define VMBLOCK_CONTROL_MOUNTPOINT "mountPoint"
+# define VMBLOCK_CONTROL_PROC_DIRNAME "fs/" VMBLOCK_CONTROL_DIRNAME
# define VMBLOCK_MOUNT_POINT "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \
"/" VMBLOCK_CONTROL_MOUNTPOINT
+# define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \
"/" VMBLOCK_CONTROL_DEVNAME
# define VMBLOCK_DEVICE_MODE O_WRONLY
-# define VMBLOCK_CONTROL(fd, op, path) write(fd, path, op)
#elif defined(sun) || defined(__FreeBSD__)
+# define VMBLOCK_FS_NAME "vmblock"
# define VMBLOCK_MOUNT_POINT "/var/run/" VMBLOCK_FS_NAME
+# define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE_MODE O_RDONLY
# if defined(sun) /* if (sun) { */
# ifdef VMX86_DEVEL
# define VMBLOCK_LIST_FILEBLOCKS _IO('v', 3)
# endif
-# define VMBLOCK_CONTROL(fd, op, path) ioctl(fd, op, path)
# elif defined(__FreeBSD__) /* } else if (FreeBSD) { */
/*
# define VMBLOCK_LIST_FILEBLOCKS _IO('Z', 3)
# define VMBLOCK_PURGE_FILEBLOCKS _IO('Z', 4)
# endif
- /*
- * FreeBSD's ioctl data parameters must be of fixed size. Guarantee a safe
- * buffer of size MAXPATHLEN by copying the user's string to one of our own.
- */
-# define VMBLOCK_CONTROL(fd, cmd, path) \
-({ \
- char tpath[MAXPATHLEN]; \
- if (path != NULL) { \
- strlcpy(tpath, path, MAXPATHLEN); \
- } \
- ioctl((fd), (cmd), tpath); \
-})
+
# endif /* } */
#else
# error "Unknown platform for vmblock."
FLAGDEFA( 1, ECX, COMMON, 3, 1, MWAIT, NO, MASK, 0, FALSE, MWAIT) \
FLAGDEFA( 1, ECX, INTEL, 4, 1, DSCPL, NO, MASK, 0, FALSE, DSCPL) \
FLAGDEFA( 1, ECX, INTEL, 5, 1, VMX, NO, MASK, 0, FALSE, VMX) \
-FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
+FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
FLAGDEF( 1, ECX, INTEL, 7, 1, EST, NO, MASK, 0, FALSE) \
FLAGDEF( 1, ECX, INTEL, 8, 1, TM2, NO, MASK, 0, FALSE) \
FLAGDEFA( 1, ECX, COMMON, 9, 1, SSSE3, YES, HOST, 0, TRUE, SSSE3) \
FLAGDEF( 81, EDX, AMD, 23, 1, MMX, YES, HOST, 0, TRUE) \
FLAGDEF( 81, EDX, AMD, 24, 1, FXSAVE, YES, HOST, 0, TRUE) \
FLAGDEFA( 81, EDX, AMD, 25, 1, FFXSR, YES, HOST, 0, FALSE, FFXSR) \
-FLAGDEF( 81, EDX, AMD, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
+FLAGDEF( 81, EDX, COMMON, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
FLAGDEFA( 81, EDX, COMMON, 27, 1, RDTSCP, YES, HOST, 0, TRUE, RDTSCP) \
FLAGDEFA( 81, EDX, COMMON, 29, 1, LM, YES, TEST, 1, FALSE, LM) \
FLAGDEFA( 81, EDX, AMD, 30, 1, 3DNOWPLUS, YES, HOST, 0, TRUE, 3DNOWPLUS) \
FLAGDEF( 8A, EDX, AMD, 3, 1, SVM_NRIP, NO, MASK, 0, FALSE) \
FIELDDEF( 8A, EDX, AMD, 4, 28, SVMEDX_RSVD, NO, MASK, 0, FALSE)
+
#define CPUID_FIELD_DATA \
CPUID_FIELD_DATA_LEVEL_0 \
CPUID_FIELD_DATA_LEVEL_1 \
CPUID_FIELD_DATA_LEVEL_81 \
CPUID_FIELD_DATA_LEVEL_8x
+
/*
* Define all field and flag values as an enum. The result is a full
* set of values taken from the table above in the form:
* macros/functions for reading cpuid fields.
*/
+#define CPUID_FAMILY_EXTENDED 15
+
/* Effective Intel CPU Families */
#define CPUID_FAMILY_486 4
#define CPUID_FAMILY_P5 5
#define CPUID_FAMILY_K8 15
#define CPUID_FAMILY_K8L 16
#define CPUID_FAMILY_K8MOBILE 17
-#define CPUID_FAMILY_EXTENDED 15
/* Intel model information */
#define CPUID_MODEL_PPRO 1
#define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown
#define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville
#define CPUID_MODEL_CORE_1D 0x1d // Dunnington
-#define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield
#define CPUID_MODEL_PIII_07 7
#define CPUID_MODEL_PIII_08 8
CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1.
{
/* Assumes the CPU manufacturer is Intel. */
+ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
+
return CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1A ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1E);
+ (
+ effectiveModel == CPUID_MODEL_NEHALEM_1A);
}
static INLINE Bool
utf16_t *modPath = NULL;
utf16_t *lastSlash;
utf16_t *wpath;
- HANDLE hFile;
- HANDLE hMapping;
+ HANDLE hFile = INVALID_HANDLE_VALUE;
+ HANDLE hMapping = NULL;
void *memMappedData = NULL;
#else
struct stat finfo;
if (hMapping) {
CloseHandle(hMapping);
}
- if (hFile) {
+ if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
}
#endif
static Bool
ProcMgr_IsProcessRunning(pid_t pid)
{
- return ((kill(pid, 0) == -1) && (errno == ESRCH));
+ return ((kill(pid, 0) == 0) || (errno == EPERM));
}
* Stops a channel, optionally destroying the channel. It's safe to call
* this function more than once.
*
+ * @internal This function does a best effort at tearing down the host-side
+ * channels, but if the host returns any failure, it still shuts
+ * down the guest channels. See bug 388777 for details.
+ *
* @param[in] chan The RPC channel instance.
* @param[in] destroy Whether to destroy the channels.
- *
- * @return TRUE on success.
*/
-static Bool
+static void
RpcInStopChannel(RpcChannel *chan,
gboolean destroy)
{
- gboolean ret = TRUE;
BackdoorChannel *bdoor = chan->_private;
ASSERT(chan->appName != NULL);
if (bdoor->out != NULL) {
- if (!bdoor->outStarted || RpcOut_stop(bdoor->out)) {
- if (destroy) {
- RpcOut_Destruct(bdoor->out);
- bdoor->out = NULL;
- }
- bdoor->outStarted = FALSE;
- } else {
- ret = FALSE;
+ if (bdoor->outStarted) {
+ RpcOut_stop(bdoor->out);
+ }
+ if (destroy) {
+ RpcOut_Destruct(bdoor->out);
+ bdoor->out = NULL;
}
+ bdoor->outStarted = FALSE;
} else {
ASSERT(!bdoor->outStarted);
}
if (bdoor->in != NULL) {
- if (!bdoor->inStarted || RpcIn_stop(bdoor->in)) {
- if (destroy) {
- RpcIn_Destruct(bdoor->in);
- bdoor->in = NULL;
- }
- bdoor->inStarted = FALSE;
- } else {
- ret = FALSE;
+ if (bdoor->inStarted) {
+ RpcIn_stop(bdoor->in);
}
+ if (destroy) {
+ RpcIn_Destruct(bdoor->in);
+ bdoor->in = NULL;
+ }
+ bdoor->inStarted = FALSE;
} else {
ASSERT(!bdoor->inStarted);
}
-
- return ret;
}
* down the "in" one wasn't, for example, although that's unlikely.
*
* @param[in] chan The RPC channel instance.
- *
- * @return TRUE on success.
*/
-static Bool
+static void
RpcInShutdown(RpcChannel *chan)
{
- return RpcInStopChannel(chan, TRUE);
+ RpcInStopChannel(chan, TRUE);
}
* @return TRUE on success.
*/
-static Bool
+static void
RpcInStop(RpcChannel *chan)
{
- return RpcInStopChannel(chan, FALSE);
+ RpcInStopChannel(chan, FALSE);
}
{
RpcChannel *chan = _chan;
- if (!chan->stop(chan) || !chan->start(chan)) {
- g_warning("Channel reset failed [%d]\n", chan->rpcErrorCount);
+ chan->stop(chan);
+ if (!chan->start(chan)) {
+ g_warning("Channel restart failed [%d]\n", chan->rpcErrorCount);
if (chan->resetCb != NULL) {
chan->resetCb(chan, FALSE, chan->resetData);
}
gchar *msg;
RpcChannel *chan = data->clientData;
- g_assert(chan->resetCheck == NULL);
- chan->resetCheck = g_idle_source_new();
- g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL);
- g_source_attach(chan->resetCheck, chan->mainCtx);
+ if (chan->resetCheck == NULL) {
+ chan->resetCheck = g_idle_source_new();
+ g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL);
+ g_source_attach(chan->resetCheck, chan->mainCtx);
+ }
msg = Str_Asprintf(NULL, "ATR %s", chan->appName);
ASSERT_MEM_ALLOC(msg);
{
size_t i;
- if (chan->shutdown != NULL && !chan->shutdown(chan)) {
- return FALSE;
+ if (chan->shutdown != NULL) {
+ chan->shutdown(chan);
}
RpcChannel_UnregisterCallback(chan, &chan->resetReg);
*
*/
+#include <string.h>
+
#include "vm_assert.h"
#include "config.h"
#include "preference.h"
return (char *) defaultValue;
}
+int32
+Config_GetTriState(int32 defaultValue,
+ const char *fmt, ...)
+{
+ return defaultValue;
+}
+
+char *
+Config_GetPathName(const char *defaultValue,
+ const char *format, ...)
+{
+ return defaultValue ? strdup(defaultValue) : NULL;
+}
+
+Bool
+Config_NotSet(const char *fmt, ...)
+{
+ return FALSE;
+}
void
System_Shutdown(Bool reboot) // IN: "reboot or shutdown" flag
{
- static char *cmd;
+ char *cmd;
if (reboot) {
- cmd = "shutdown -r now";
+#if defined(sun)
+ cmd = "/usr/sbin/shutdown -g 0 -i 6 -y";
+#else
+ cmd = "/sbin/shutdown -r now";
+#endif
} else {
#if __FreeBSD__
- cmd = "shutdown -p now";
+ cmd = "/sbin/shutdown -p now";
+#elif defined(sun)
+ cmd = "/usr/sbin/shutdown -g 0 -i 5 -y";
#else
- cmd = "shutdown -h now";
+ cmd = "/sbin/shutdown -h now";
#endif
}
if (system(cmd) == -1) {
} // System_SetLDPath
-/*
- *-----------------------------------------------------------------------------
- *
- * System_WritePidfile --
- *
- * Write a PID into a pidfile.
- *
- * Originally from the POSIX guestd as GuestdWritePidfile.
- *
- * Return value:
- * TRUE on success
- * FALSE on failure (detail is displayed on stderr)
- *
- * Side effects:
- * This function is not thread-safe. May display error messages on
- * stderr.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-System_WritePidfile(char const *fileName, // IN: Path where we'll write pid
- pid_t pid) // IN: C'mon, really?
-{
- FILE *pidFile;
- Bool success = FALSE;
-
- pidFile = fopen(fileName, "w+");
- if (pidFile == NULL) {
- fprintf(stderr, "Unable to open the \"%s\" PID file: %s.\n\n", fileName,
- strerror(errno));
-
- return FALSE;
- }
-
- if (fprintf(pidFile, "%"FMTPID"\n", pid) < 0) {
- fprintf(stderr, "Unable to write the \"%s\" PID file: %s.\n\n", fileName,
- strerror(errno));
- } else {
- success = TRUE;
- }
-
- if (fclose(pidFile)) {
- fprintf(stderr, "Unable to close the \"%s\" PID file: %s.\n\n", fileName,
- strerror(errno));
-
- return FALSE;
- }
-
- return success;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * System_Daemon --
- *
- * Analog to daemon(3), but optionally guarantees child's PID is written
- * to a pidfile before the parent exits.
- *
- * Originally from the short-lived Mac OS guestd, as Mac OS X does not
- * provide daemon(3). Additionally, the "optionally guaranteed pidfile"
- * concept is another motivation for this function.
- *
- * Results:
- * TRUE on success.
- * FALSE on any failure (e.g., fork, setsid, WritePidfile, etc.)
- *
- * Side effects:
- * Parent will exit if fork() succeeds.
- * Caller is expected to be able to catch SIGPIPE.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-System_Daemon(Bool nochdir,
- // IN: If TRUE, will -not- chdir("/").
- Bool noclose,
- // IN: If TRUE, will -not- redirect stdin, stdout, and stderr
- // to /dev/null.
- const char *pidFile)
- // IN: If non-NULL, will write the child's PID to this file.
-{
- int fds[2];
- pid_t child;
- char buf;
-
- if (pipe(fds) == -1) {
- fprintf(stderr, "pipe failed: %s\n", strerror(errno));
- return FALSE;
- }
-
- child = fork();
- if (child == -1) {
- fprintf(stderr, "fork failed: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (child) { /* Parent */
- ssize_t actual;
-
- /* Close unused write end of the pipe. */
- close(fds[1]);
-
- /*
- * Wait for the child to finish its critical initialization before the
- * parent exits.
- */
- do {
- actual = read(fds[0], &buf, sizeof buf);
- } while (actual == -1 && errno == EINTR);
-
- if (actual == -1) {
- fprintf(stderr, "read from pipe failed: %s\n", strerror(errno));
- _exit(EXIT_FAILURE);
- }
-
- _exit(EXIT_SUCCESS);
- } else { /* Child */
- /* Close unused read end of the pipe. */
- close(fds[0]);
-
- /*
- * The parent's caller might want to kill the child as soon as the
- * parent exits, so better guarantee that by that time the child's PID
- * has been written to the PID file.
- *
- * Note that because the parent knows the child's PID, the parent
- * could do this if needed. But because the parent cannot do the
- * setsid() below, the child might as well do both things here.
- */
- if (pidFile) {
- if (!System_WritePidfile(pidFile, getpid())) {
- goto kidfail;
- }
- }
-
- /*
- * The parent's caller might want to destroy the session as soon as
- * the parent exits, so better guarantee that by that time the child
- * has created its own new session.
- */
- if (setsid() == -1) {
- fprintf(stderr, "setsid failed: %s\n", strerror(errno));
- goto kidfail;
- }
-
- /*
- * The child has finished its critical initialization. Notify the
- * parent that it can exit.
- *
- * We are writing the first byte to the pipe. This cannot possibly
- * block (otherwise communication over a pipe would be impossible).
- * Consequently it cannot be interrupted by a signal either.
- *
- * See pipe(7) for more information.
- *
- * The caller registered a signal handler for SIGPIPE, right?! We
- * won't treat EPIPE as an error, because we'd like to carry on with
- * our own life, even if our parent -did- abandon us. ;_;
- */
- if (write(fds[1], &buf, sizeof buf) == -1) {
- fprintf(stderr, "write failed: %s\n", strerror(errno));
- close(fds[1]);
- return FALSE;
- }
- close(fds[1]);
-
- if (!nochdir && (chdir("/") == -1)) {
- fprintf(stderr, "chdir failed: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (!noclose) {
- /*
- * The child has finished its initialization, and does not need to
- * output anything to stderr anymore. Re-assign all standard file
- * file descriptors.
- */
- int nullFd;
-
- nullFd = open("/dev/null", O_RDWR);
- if (nullFd == -1) {
- fprintf(stderr, "open of /dev/null failed: %s\n",
- strerror(errno));
- return FALSE;
- }
-
- if ((dup2(nullFd, STDIN_FILENO) == -1) ||
- (dup2(nullFd, STDOUT_FILENO) == -1) ||
- (dup2(nullFd, STDERR_FILENO) == -1)) {
- fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
- close(nullFd);
- return FALSE;
- }
- }
- }
-
- return TRUE;
-
-kidfail:
- close(fds[1]);
- return FALSE;
-}
-
-
/*
*-----------------------------------------------------------------------------
*
*
* Every value created by the wrapper begins with a 1 or 0 to indicate
* whether the value was set in the native environment. Based on this:
- * VMWARE_FOO="1foo" -> FOO="foo"
- * VMWARE_FOO="1" -> FOO=""
- * VMWARE_FOO="0" -> FOO is unset in the native environment
+ * VMWARE_FOO="1foo" -> FOO="foo"
+ * VMWARE_FOO="1" -> FOO=""
+ * VMWARE_FOO="0 VMWARE_UNDEFINED" -> FOO is unset in the native environment
*
* Variables without the VMWARE_ prefix are just copied over to the new
* environment. Note, of course, that VMWARE_-prefixed variables take
* figure out the original environment variable name (by just indexing
* past the prefix) and value (by indexing past the "was this variable
* in the native environment?" marker).
+ *
+ * XXX Should we move this marker to a separate header?
*/
char *realKey = &key[prefixLength];
- char *realValue = (value[0] == '0') ? NULL : Util_SafeStrdup(&value[1]);
+ char *realValue = (strcmp(value, "0 VMWARE_UNDEFINED") == 0)
+ ? NULL
+ : Util_SafeStrdup(&value[1]);
HashTable_ReplaceOrInsert(environTable, realKey, realValue);
} else {
HashTable_LookupOrInsert(environTable, key, value);
};
-/*
- * Thread-safe hash table to speed up encoding name -> IANA table
- * index lookups.
- */
-static HashTable *encCache = NULL;
-
-
/*
*-----------------------------------------------------------------------------
*
currentResult = result;
for (currentResult = result; *encodingName != '\0'; encodingName++) {
+ // The explicit cast from char to int is necessary for Netware builds.
if (isalnum((int) *encodingName)) {
*currentResult = tolower(*encodingName);
currentResult++;
static int
UnicodeIANALookup(const char *encodingName) // IN
{
- char *name;
+ /*
+ * Thread-safe hash table to speed up encoding name -> IANA table
+ * index lookups.
+ */
+ static Atomic_Ptr htPtr;
+ static HashTable *encCache = NULL;
+
+ char *name = NULL;
char *candidate = NULL;
const char *p;
int i;
int j;
int acp;
void *idx;
+ size_t windowsPrefixLen = sizeof "windows-" - 1 /* NUL */;
- if (encCache && HashTable_Lookup(encCache, encodingName, (void **) &idx)) {
+ if (UNLIKELY(encCache == NULL)) {
+ encCache = HashTable_AllocOnce(&htPtr, 128, HASH_ISTRING_KEY | HASH_FLAG_ATOMIC |
+ HASH_FLAG_COPYKEY, free);
+ }
+
+ if (encCache && HashTable_Lookup(encCache, encodingName, &idx)) {
return (int)(uintptr_t)idx;
}
- name = UnicodeNormalizeEncodingName(encodingName);
-
/*
* check for Windows-xxxx encoding names generated from GetACP()
* code page numbers, see: CodeSetOld_GetCurrentCodeSet()
*/
- if (!strncmp(encodingName, "windows-", strlen("windows-"))) {
- p = encodingName + strlen("windows-");
+ if ( strncmp(encodingName, "windows-", windowsPrefixLen) == 0
+ || strncmp(encodingName, "Windows-", windowsPrefixLen) == 0) {
+ p = encodingName + windowsPrefixLen;
acp = 0;
+
+ // The explicit cast from char to int is necessary for Netware builds.
while (*p && isdigit((int)*p)) {
acp *= 10;
acp += *p - '0';
}
}
}
-
+
+ // Try the raw names first to avoid the expense of normalizing everything.
+ for (i = 0; i < ARRAYSIZE(xRef); i++) {
+ for (j = 0; (p = xRef[i].names[j]) != NULL; j++) {
+ if (strcmp(encodingName, p) == 0) {
+ goto done;
+ }
+ }
+ }
+
+ name = UnicodeNormalizeEncodingName(encodingName);
for (i = 0; i < ARRAYSIZE(xRef); i++) {
for (j = 0; (p = xRef[i].names[j]) != NULL; j++) {
candidate = UnicodeNormalizeEncodingName(p);
- if (!strcmp(name, candidate)) {
+ if (strcmp(name, candidate) == 0) {
goto done;
}
free(candidate);
goto exit;
}
- encCache = HashTable_Alloc(128, HASH_ISTRING_KEY | HASH_FLAG_ATOMIC |
- HASH_FLAG_COPYKEY, free);
- if (encCache == NULL) {
-#ifndef N_PLAT_NLM
- snprintf(panicMsg, sizeof panicMsg, "HashTable_Alloc failed.\n");
-#endif
- goto exit;
- }
-
// UTF-8 native encoding for these two
#if !defined(__APPLE__) && !defined(VMX86_SERVER)
encoding = Unicode_EncodingNameToEnum(CodeSet_GetCurrentCodeSet());
static UnityCommandElem unityCommandTable[] = {
{ UNITY_RPC_WINDOW_CLOSE, UnityPlatformCloseWindow },
+ { UNITY_RPC_WINDOW_SHOW, UnityPlatformShowWindow },
+ { UNITY_RPC_WINDOW_HIDE, UnityPlatformHideWindow },
{ UNITY_RPC_WINDOW_MINIMIZE, UnityPlatformMinimizeWindow },
{ UNITY_RPC_WINDOW_UNMINIMIZE, UnityPlatformUnminimizeWindow },
{ UNITY_RPC_WINDOW_MAXIMIZE, UnityPlatformMaximizeWindow },
RpcIn_RegisterCallback(rpcIn, UNITY_RPC_EXIT, UnityTcloExit, NULL);
RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_MOVE_RESIZE,
UnityTcloMoveResizeWindow, NULL);
+ RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_SHOW,
+ UnityTcloWindowCommand, NULL);
+ RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_HIDE,
+ UnityTcloWindowCommand, NULL);
RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_MINIMIZE,
UnityTcloWindowCommand, NULL);
RpcIn_RegisterCallback(rpcIn, UNITY_RPC_WINDOW_UNMINIMIZE,
UnityWindowId *windows,
unsigned int windowCount);
Bool UnityPlatformCloseWindow(UnityPlatform *up, UnityWindowId window);
+Bool UnityPlatformShowWindow(UnityPlatform *up, UnityWindowId window);
+Bool UnityPlatformHideWindow(UnityPlatform *up, UnityWindowId window);
Bool UnityPlatformMinimizeWindow(UnityPlatform *up, UnityWindowId window);
Bool UnityPlatformUnminimizeWindow(UnityPlatform *up, UnityWindowId window);
Bool UnityPlatformMaximizeWindow(UnityPlatform *up, UnityWindowId window);
}
+/*
+ *----------------------------------------------------------------------------
+ *
+ * UnityPlatformShowWindow --
+ *
+ * Makes hidden Window visible. If the Window is already visible, it stays
+ * visible. Window reappears at its original location. A minimized window
+ * reappears as minimized.
+ *
+ * Results:
+ *
+ * FALSE if the Window handle is invalid.
+ * TRUE otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+UnityPlatformShowWindow(UnityPlatform *up, // IN
+ UnityWindowId window) // IN
+{
+ UnityPlatformWindow *upw;
+
+ ASSERT(up);
+
+ upw = UPWindow_Lookup(up, window);
+
+ if (!upw || !upw->clientWindow) {
+ Debug("Hiding FAILED!\n");
+ return FALSE;
+ }
+
+ if (upw->isHidden) {
+ Atom data[5] = {0, 0, 0, 0, 0};
+
+ /*
+ * Unfortunately the _NET_WM_STATE messages only work for windows that are already
+ * mapped, i.e. not iconified or withdrawn.
+ */
+ if (!upw->isMinimized) {
+ XMapRaised(up->display, upw->clientWindow);
+ }
+
+ data[0] = _NET_WM_STATE_REMOVE;
+ data[1] = up->atoms._NET_WM_STATE_HIDDEN;
+ data[3] = 2; // Message is from the pager/taskbar
+ UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
+ up->atoms._NET_WM_STATE, 32, 4, data);
+
+ upw->wantInputFocus = TRUE;
+ upw->isHidden = FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * UnityPlatformHideWindow --
+ *
+ * Hides window. If the window is already hidden it stays hidden. Hides
+ * maximized and minimized windows too.
+ *
+ * Results:
+ * FALSE if the Window handle is invalid.
+ * TRUE otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+UnityPlatformHideWindow(UnityPlatform *up, // IN
+ UnityWindowId window) // IN
+{
+ UnityPlatformWindow *upw;
+
+ ASSERT(up);
+
+ upw = UPWindow_Lookup(up, window);
+
+ if (!upw
+ || !upw->clientWindow) {
+ Debug("Hiding FAILED!\n");
+ return FALSE;
+ }
+
+ if (!upw->isHidden) {
+ Atom data[5] = {0, 0, 0, 0, 0};
+
+ upw->isHidden = TRUE;
+
+ data[0] = _NET_WM_STATE_ADD;
+ data[1] = up->atoms._NET_WM_STATE_HIDDEN;
+ data[3] = 2; // Message is from a pager/taskbar/etc.
+ UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
+ up->atoms._NET_WM_STATE, 32, 4, data);
+ }
+
+ return TRUE;
+}
+
+
/*
*----------------------------------------------------------------------------
*
Bool
Hostinfo_GetLoadAverage(uint32 *avg) // IN/OUT
{
- float avg0;
+ float avg0 = 0;
if (!HostinfoGetLoadAverage(&avg0, NULL, NULL)) {
return FALSE;
void
Hostinfo_LogLoadAverage(void)
{
- float avg0, avg1, avg2;
+ float avg0 = 0, avg1 = 0, avg2 = 0;
if (!HostinfoGetLoadAverage(&avg0, &avg1, &avg2)) {
return;
char **argsLocalEncoding = NULL;
ASSERT_ON_COMPILE(sizeof (errno) <= sizeof err);
+ ASSERT(args);
+ ASSERT(path && File_IsFile(path));
if (pipe(pipeFds) == -1) {
err = Err_Errno();
goto cleanup;
}
- if (fcntl(F_SETFD, pipeFds[1], 1) == -1) {
+ if (fcntl(pipeFds[1], F_SETFD, 1) == -1) {
err = Err_Errno();
Warning("%s: Couldn't set close-on-exec for fd %d, error %u.\n",
__FUNCTION__, pipeFds[1], err);
}
if (execv(pathLocalEncoding, argsLocalEncoding) == -1) {
- uint32 err = Err_Errno();
- Warning("%s: Couldn't exec %s, error %u.\n",
+ err = Err_Errno();
+ Warning("%s: Couldn't exec %s, error %d.\n",
__FUNCTION__, path, err);
// Let the original process know we failed to exec.
if (write(pipeFds[1], &err, sizeof err) == -1) {
void *cbData) // IN/OUT: Our status
{
struct UtilBacktraceFromPointerData *data = cbData;
- uintptr_t cfa = _Unwind_GetCFA(ctx);
- void *encl_func_addr;
- Dl_info dli;
-
+ uintptr_t cfa = _Unwind_GetCFA(ctx);
/*
* Stack grows down. So if we are below basePtr, do nothing...
#ifndef VM_X86_64
# error You should not build this on 32bit - there is no eh_frame there.
#endif
- encl_func_addr = _Unwind_FindEnclosingFunction((void *)_Unwind_GetIP(ctx));
- if ( (dladdr(encl_func_addr, &dli) != 0) ||
- (dladdr((void *)_Unwind_GetIP(ctx), &dli) != 0 )) {
+ void *enclFuncAddr;
+ Dl_info dli;
+
+#ifdef __linux__
+ enclFuncAddr = _Unwind_FindEnclosingFunction((void *)_Unwind_GetIP(ctx));
+#else
+ enclFuncAddr = NULL;
+#endif
+ if (dladdr(enclFuncAddr, &dli) ||
+ dladdr((void *)_Unwind_GetIP(ctx), &dli)) {
data->outFunc(data->outFuncData,
"SymBacktrace[%u] %016lx rip=%016lx in function %s "
"in object %s loaded at %016lx\n",
#if !defined(_WIN32) && !defined(N_PLAT_NLM) && !defined(VMX86_TOOLS)
/*
* We do a separate pass here that includes symbols in order to
- * make sure the base backtrace that does not call dladdr etc.
- * is safely produced
+ * make sure the base backtrace that does not call dladdr() etc.
+ * is safely produced.
*/
data.basePtr = (uintptr_t)basePtr;
data.outFunc = outFunc;
#if !defined(_WIN32) && !defined(N_PLAT_NLM) && !defined(VMX86_TOOLS)
/*
* We do a separate pass here that includes symbols in order to
- * make sure the base backtrace that does not call dladdr etc.
- * is safely produced
+ * make sure the base backtrace that does not call dladdr() etc.
+ * is safely produced.
*/
x = basePtr;
for (i = 0; i < 256; i++) {
(uintptr_t) x - (uintptr_t) basePtr > 0x8000) {
break;
}
- if ( dladdr((uintptr_t *)x[1], &dli) != 0 ) {
+ if (dladdr((uintptr_t *)x[1], &dli)) {
outFunc(outFuncData, "SymBacktrace[%d] %#08x eip %#08x in function %s "
"in object %s loaded at %#08x\n",
i, x[0], x[1], dli.dli_sname, dli.dli_fname,
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * scriptOps.c --
- *
- * Functions for handling freeze/thaw scripts.
- */
-
-#include "vmBackup.h"
-#include "vmBackupInt.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm_basic_defs.h"
-#include "debug.h"
-#include "file.h"
-#include "guestApp.h"
-#include "procMgr.h"
-#include "str.h"
-#include "util.h"
-#include "codeset.h"
-
-
-typedef struct VmBackupScript {
- char *path;
- ProcMgr_AsyncProc *proc;
-} VmBackupScript;
-
-
-typedef struct VmBackupScriptOp {
- VmBackupOp callbacks;
- Bool canceled;
- Bool thawFailed;
- VmBackupScriptType type;
- VmBackupState *state;
-} VmBackupScriptOp;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupGetScriptPath --
- *
- * Returns the path where the scripts to be executed reside.
- *
- * Result
- * A string with the requested path.
- *
- * Side effects:
- * Allocates memory for the path.
- *
- *-----------------------------------------------------------------------------
- */
-
-char *
-VmBackupGetScriptPath(void)
-{
- char *scriptPath = NULL;
- char *installPath = GuestApp_GetInstallPath();
-
- if (installPath == NULL) {
- return NULL;
- }
-
- scriptPath = Str_Asprintf(NULL, "%s%s%s", installPath, DIRSEPS, "backupScripts.d");
- free(installPath);
-
- return scriptPath;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupRunNextScript --
- *
- * Runs the next script for the given operation. If thawing (or running
- * scripts after a failure), this function will try as much as possible
- * to start a script, meaning that if it fails to start a script it will
- * try to start the preceding one until one script is run, or it runs out
- * of scripts to try.
- *
- * Results:
- * -1: an error occurred.
- * 0: no more scripts to run.
- * 1: script was started.
- *
- * Side effects:
- * Increments (or decrements) the "current script" index in the backup state.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-VmBackupRunNextScript(VmBackupScriptOp *op) // IN/OUT
-{
- const char *scriptOp;
- int ret = 0;
- ssize_t index;
- VmBackupScript *scripts = op->state->scripts;
-
- switch (op->type) {
- case VMBACKUP_SCRIPT_FREEZE:
- index = ++op->state->currentScript;
- scriptOp = "freeze";
- break;
-
- case VMBACKUP_SCRIPT_FREEZE_FAIL:
- index = --op->state->currentScript;
- scriptOp = "freezeFail";
- break;
-
- case VMBACKUP_SCRIPT_THAW:
- index = --op->state->currentScript;
- scriptOp = "thaw";
- break;
-
- default:
- NOT_REACHED();
- }
-
- while (index >= 0 && scripts[index].path != NULL) {
- char *cmd;
-
- cmd = Str_Asprintf(NULL, "\"%s\" %s", scripts[index].path, scriptOp);
- if (cmd == NULL) {
- index = --op->state->currentScript;
- op->thawFailed = TRUE;
- }
-
- if ((scripts[index].proc = ProcMgr_ExecAsync(cmd, NULL)) == NULL) {
- if (op->type == VMBACKUP_SCRIPT_FREEZE) {
- ret = -1;
- break;
- } else {
- index = --op->state->currentScript;
- op->thawFailed = TRUE;
- }
- } else {
- ret = 1;
- break;
- }
-
- /* This happens if all thaw/fail scripts failed to start. */
- if (index == -1 && scripts[0].proc == NULL) {
- ret = -1;
- }
- }
-
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupStringCompare --
- *
- * Comparison function used to sort the script list in ascending order.
- *
- * Result
- * The result of strcmp(str1, str2).
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-VmBackupStringCompare(const void *str1, // IN
- const void *str2) // IN
-{
- return strcmp(* (char * const *) str1,* (char * const *) str2);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupScriptOpQuery --
- *
- * Checks the status of the current running script. If the script is
- * finished, run the next script in the queue or, if no scripts are left,
- * return a "finished" status.
- *
- * Result
- * The status of the operation.
- *
- * Side effects:
- * Might start a new process.
- *
- *-----------------------------------------------------------------------------
- */
-
-static VmBackupOpStatus
-VmBackupScriptOpQuery(VmBackupOp *_op) // IN
-{
- VmBackupOpStatus ret = VMBACKUP_STATUS_PENDING;
- VmBackupScriptOp *op = (VmBackupScriptOp *) _op;
- VmBackupScript *scripts = op->state->scripts;
- VmBackupScript *currScript = NULL;
-
- if (scripts != NULL && op->state->currentScript >= 0) {
- currScript = &scripts[op->state->currentScript];
- }
-
- if (op->canceled) {
- ret = VMBACKUP_STATUS_CANCELED;
- goto exit;
- } else if (scripts == NULL || currScript == NULL || currScript->proc == NULL) {
- ret = VMBACKUP_STATUS_FINISHED;
- goto exit;
- }
-
- if (!ProcMgr_IsAsyncProcRunning(currScript->proc)) {
- int exitCode;
- Bool succeeded;
-
- succeeded = (ProcMgr_GetExitCode(currScript->proc, &exitCode) == 0 &&
- exitCode == 0);
- ProcMgr_Free(currScript->proc);
- currScript->proc = NULL;
-
- /*
- * If thaw scripts fail, keep running and only notify the failure after
- * all others have run.
- */
- if (!succeeded) {
- if (op->type == VMBACKUP_SCRIPT_FREEZE) {
- ret = VMBACKUP_STATUS_ERROR;
- goto exit;
- } else if (op->type == VMBACKUP_SCRIPT_THAW) {
- op->thawFailed = TRUE;
- }
- }
-
- switch (VmBackupRunNextScript(op)) {
- case -1:
- ret = VMBACKUP_STATUS_ERROR;
- break;
-
- case 0:
- ret = op->thawFailed ? VMBACKUP_STATUS_ERROR : VMBACKUP_STATUS_FINISHED;
- break;
-
- default:
- break;
- }
- }
-
-exit:
- if (ret == VMBACKUP_STATUS_ERROR) {
- /* Report the script error to the host */
- op->state->SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR,
- VMBACKUP_SCRIPT_ERROR,
- "Custom script failed.");
- }
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupScriptOpRelease --
- *
- * Frees memory allocated for the state object. Behavior is undefined
- * if the memory is freed before the query function says the operation
- * if finished.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-VmBackupScriptOpRelease(VmBackupOp *_op) // IN
-{
- size_t i;
- VmBackupScriptOp *op = (VmBackupScriptOp *) _op;
-
- if (op->type != VMBACKUP_SCRIPT_FREEZE && op->state->scripts != NULL) {
- VmBackupScript *scripts = op->state->scripts;
- for (i = 0; scripts[i].path != NULL; i++) {
- free(scripts[i].path);
- if (scripts[i].proc != NULL) {
- ProcMgr_Free(scripts[i].proc);
- }
- }
- free(op->state->scripts);
- op->state->scripts = NULL;
- op->state->currentScript = 0;
- }
-
- free(op);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupScriptOpCancel --
- *
- * Cancels the current operation. Kills any currently running script and
- * flags the operation as canceled.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-VmBackupScriptOpCancel(VmBackupOp *_op) // IN
-{
- VmBackupScriptOp *op = (VmBackupScriptOp *) _op;
- VmBackupScript *scripts = op->state->scripts;
- VmBackupScript *currScript = NULL;
- ProcMgr_Pid pid;
-
- if (scripts != NULL) {
- currScript = &scripts[op->state->currentScript];
- ASSERT(currScript->proc != NULL);
-
- pid = ProcMgr_GetPid(currScript->proc);
- if (!ProcMgr_KillByPid(pid)) {
- // XXX: what to do in this situation? other than log and cry?
- } else {
- int exitCode;
- ProcMgr_GetExitCode(currScript->proc, &exitCode);
- }
- }
-
- op->canceled = TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupNewScriptOp --
- *
- * Creates a new state object to monitor the execution of OnFreeze or
- * OnThaw scripts. This will identify all the scripts in the backup scripts
- * directory and add them to an execution queue.
- *
- * Note: there is some state created when instantianting the "OnFreeze"
- * scripts which is only released after the "OnThaw" scripts are run. So
- * the caller has to make sure that thaw (or fail) scripts are run every
- * time the freeze scripts are run.
- *
- * Result
- * A pointer to the operation state, or NULL on failure.
- *
- * Side effects:
- * If there are scripts to be executed, the first one is started.
- *
- *-----------------------------------------------------------------------------
- */
-
-VmBackupOp *
-VmBackupNewScriptOp(VmBackupScriptType type, // IN
- VmBackupState *state) // IN
-{
- Bool fail = FALSE;
- char **fileList = NULL;
- char *scriptDir = NULL;
- int numFiles = 0;
- size_t i;
- VmBackupScriptOp *op = NULL;
-
- scriptDir = VmBackupGetScriptPath();
- if (scriptDir == NULL) {
- goto exit;
- }
-
- op = calloc(1, sizeof *op);
- if (op == NULL) {
- goto exit;
- }
-
- op->state = state;
- op->type = type;
- op->callbacks.queryFn = VmBackupScriptOpQuery;
- op->callbacks.cancelFn = VmBackupScriptOpCancel;
- op->callbacks.releaseFn = VmBackupScriptOpRelease;
-
- Debug("Trying to run scripts from %s\n", scriptDir);
-
- /*
- * Load the list of scripts to run when freezing. The same list will be
- * used later in case of failure, or when thawing, in reverse order.
- *
- * This logic won't recurse into directories, so only files directly under
- * the script dir will be considered.
- */
- if (type == VMBACKUP_SCRIPT_FREEZE && File_IsDirectory(scriptDir)) {
- size_t scriptCount = 0;
-
- state->scripts = NULL;
- state->currentScript = 0;
- numFiles = File_ListDirectory(scriptDir, &fileList);
-
- if (numFiles > 0) {
- VmBackupScript *scripts;
-
- scripts = calloc(1, (numFiles + 1) * sizeof *scripts);
- if (scripts == NULL) {
- fail = TRUE;
- goto exit;
- }
-
- state->scripts = scripts;
-
- /*
- * VmBackupRunNextScript increments the index, so need to make it point
- * to "before the first script".
- */
- state->currentScript = -1;
-
- if (numFiles > 1) {
- qsort(fileList, (size_t) numFiles, sizeof *fileList, VmBackupStringCompare);
- }
-
- for (i = 0; i < numFiles; i++) {
- char *script;
-
- script = Str_Asprintf(NULL, "%s%c%s", scriptDir, DIRSEPC, fileList[i]);
- if (script == NULL) {
- fail = TRUE;
- goto exit;
- } else if (File_IsFile(script)) {
- scripts[scriptCount++].path = script;
- } else {
- free(script);
- }
- }
- }
- }
-
- /*
- * If there are any scripts to be executed, start the first one. If we get to
- * this point, we won't free the scripts array until VmBackupScriptOpRelease
- * is called after thawing (or after the sync provider failed and the "fail"
- * scripts are run).
- */
- fail = (state->scripts != NULL && VmBackupRunNextScript(op) == -1);
-
-exit:
- /* Free the file list. */
- for (i = 0; i < numFiles; i++) {
- free(fileList[i]);
- }
- free(fileList);
-
- if (fail && op != NULL) {
- VmBackup_Release((VmBackupOp *) op);
- op = NULL;
- }
- free(scriptDir);
- return (VmBackupOp *) op;
-}
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * stateMachine.c --
- *
- * Implements a generic state machine for executing backup operations
- * asynchronously. Since VSS is based on an asynchronous poolling model,
- * we're basing all backup operations on a similar model controlled by this
- * state machine, even if it would be more eficient to use an event-driven
- * approach in some cases.
- *
- * Overall order of execution for when no errors occur:
- *
- * Start -> OnFreeze -> run sync provider -> OnThaw -> Finalize
- *
- * The sync provider state machine depends on the particular implementation.
- * For the sync driver, it enables the driver and waits for a "snapshot done"
- * message before finishing. For the VSS subsystem, the sync provider just
- * implements a VSS backup cycle.
- */
-
-#include "vmBackup.h"
-#include "vmBackupInt.h"
-#include "vmbackup_def.h"
-
-#include <errno.h>
-#include <string.h>
-
-#include "vm_basic_defs.h"
-#include "vm_assert.h"
-
-#include "debug.h"
-#include "eventManager.h"
-#include "posix.h"
-#include "file.h"
-#include "fileIO.h"
-#include "guestApp.h"
-#include "rpcout.h"
-#include "str.h"
-#include "strutil.h"
-#include "util.h"
-#include "vmstdio.h"
-#include "conf.h"
-
-#define VMBACKUP_ENQUEUE_EVENT() { \
- gBackupState->timerEvent = EventManager_Add(gEventQueue, \
- gBackupState->pollPeriod,\
- VmBackupAsyncCallback, \
- NULL); \
- ASSERT_MEM_ALLOC(gBackupState->timerEvent); \
-}
-
-static DblLnkLst_Links *gEventQueue = NULL;
-static VmBackupState *gBackupState = NULL;
-static VmBackupSyncProvider *gSyncProvider = NULL;
-static Bool gLoggingEnabled = FALSE;
-
-static void DebugOutput(const char *fmt, ...);
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupKeepAliveCallback --
- *
- * Sends a keep alive backup event to the VMX.
- *
- * Result
- * TRUE.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupKeepAliveCallback(void *clientData) // IN
-{
- DebugOutput("*** %s\n", __FUNCTION__);
- ASSERT(gBackupState != NULL);
- gBackupState->keepAlive = NULL;
- gBackupState->SendEvent(VMBACKUP_EVENT_KEEP_ALIVE, 0, "");
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupSendEvent --
- *
- * Sends a command to the VMX asking it to update VMDB about a new
- * backup event.
- *
- * Result
- * Whether sending the message succeeded.
- *
- * Side effects:
- * Restarts the keep alive timer.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupSendEvent(const char *event, // IN: event name
- const uint32 code, // IN: result code
- const char *desc) // IN: message related to the code
-{
- Bool success;
- ASSERT(gBackupState != NULL);
-
- DebugOutput("*** %s\n", __FUNCTION__);
- if (gBackupState->keepAlive != NULL) {
- EventManager_Remove(gBackupState->keepAlive);
- }
-
- success = RpcOut_sendOne(NULL, NULL,
- VMBACKUP_PROTOCOL_EVENT_SET" %s %u %s",
- event, code, desc);
-
- if (!success) {
- DebugOutput("VmBackup: failed to send event to the VMX.\n");
- }
-
- gBackupState->keepAlive = EventManager_Add(gEventQueue,
- VMBACKUP_KEEP_ALIVE_PERIOD / 20,
- VmBackupKeepAliveCallback,
- NULL);
- ASSERT_MEM_ALLOC(gBackupState->keepAlive);
- return success;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupFinalize --
- *
- * Cleans up the backup state object and sends a "done" event to
- * the VMX.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-VmBackupFinalize(void)
-{
- ASSERT(gBackupState != NULL);
- DebugOutput("*** %s\n", __FUNCTION__);
-
- if (gBackupState->currentOp != NULL) {
- VmBackup_Cancel(gBackupState->currentOp);
- VmBackup_Release(gBackupState->currentOp);
- }
-
- gBackupState->SendEvent(VMBACKUP_EVENT_REQUESTOR_DONE, VMBACKUP_SUCCESS, "");
-
- if (gBackupState->timerEvent != NULL) {
- EventManager_Remove(gBackupState->timerEvent);
- }
-
- if (gBackupState->keepAlive != NULL) {
- EventManager_Remove(gBackupState->keepAlive);
- }
-
- free(gBackupState->volumes);
- free(gBackupState);
- gBackupState = NULL;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupStartScripts --
- *
- * Starts the execution of the scripts for the given action type.
- *
- * Result
- * TRUE, unless starting the scripts fails for some reason.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupStartScripts(VmBackupScriptType type, // IN
- VmBackupCallback callback) // IN
-{
- const char *opName;
- DebugOutput("*** %s\n", __FUNCTION__);
-
- switch (type) {
- case VMBACKUP_SCRIPT_FREEZE:
- opName = "VmBackupOnFreeze";
- break;
-
- case VMBACKUP_SCRIPT_FREEZE_FAIL:
- opName = "VmBackupOnFreezeFail";
- break;
-
- case VMBACKUP_SCRIPT_THAW:
- opName = "VmBackupOnThaw";
- break;
-
- default:
- NOT_REACHED();
- }
-
- if (!VmBackup_SetCurrentOp(gBackupState,
- VmBackupNewScriptOp(type, gBackupState),
- callback,
- opName)) {
- gBackupState->SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR,
- VMBACKUP_SCRIPT_ERROR,
- "Error when starting backup scripts.");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupAsyncCallback --
- *
- * Callback for the event manager. Checks the status of the current
- * async operation being monitored, and calls the queued operations
- * as needed.
- *
- * Result
- * TRUE.
- *
- * Side effects:
- * Several, depending on the backup state.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupAsyncCallback(void *clientData) // IN
-{
- Bool finalize = FALSE;
-
- DebugOutput("*** %s\n", __FUNCTION__);
- ASSERT(gBackupState != NULL);
-
- gBackupState->timerEvent = NULL;
-
- if (gBackupState->currentOp != NULL) {
- VmBackupOpStatus status;
-
- DebugOutput("VmBackupAsyncCallback: checking %s\n",
- gBackupState->currentOpName);
- status = VmBackup_QueryStatus(gBackupState->currentOp);
-
- switch (status) {
- case VMBACKUP_STATUS_PENDING:
- goto exit;
-
- case VMBACKUP_STATUS_FINISHED:
- DebugOutput("Async request completed\n");
- VmBackup_Release(gBackupState->currentOp);
- gBackupState->currentOp = NULL;
- break;
-
- default:
- {
- Bool freeMsg = TRUE;
- char *errMsg = Str_Asprintf(NULL,
- "Asynchronous operation failed: %s\n",
- gBackupState->currentOpName);
- if (errMsg == NULL) {
- freeMsg = FALSE;
- errMsg = "Asynchronous operation failed.";
- }
- gBackupState->SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR,
- VMBACKUP_UNEXPECTED_ERROR,
- errMsg);
- if (freeMsg) {
- free(errMsg);
- }
-
- VmBackup_Release(gBackupState->currentOp);
- gBackupState->currentOp = NULL;
- gBackupState->syncProviderFailed = gBackupState->syncProviderRunning;
-
- /*
- * If we get an error when running the freeze scripts, we want to
- * schedule the "fail" scripts to run.
- */
- if (!gBackupState->syncProviderRunning &&
- gBackupState->scripts != NULL) {
- gBackupState->callback = NULL;
- finalize = !VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE_FAIL, NULL);
- }
- goto exit;
- }
- }
- }
-
- /*
- * Keep calling the registered callback until it's either NULL, or
- * an asynchronous operation is scheduled.
- */
- while (gBackupState->callback != NULL) {
- Bool cbRet;
- VmBackupCallback cb = gBackupState->callback;
- gBackupState->callback = NULL;
-
- cbRet = cb(gBackupState);
- if (cbRet) {
- if (gBackupState->currentOp != NULL || gBackupState->forceRequeue) {
- goto exit;
- }
- } else {
- /*
- * Finalize the backup operation, unless the sync provider is still
- * active. In which case, delay finalization until after the sync
- * provider is finished cleaning up after itself.
- */
- finalize = gBackupState->syncProviderFailed ||
- !gBackupState->syncProviderRunning;
- gBackupState->syncProviderFailed = gBackupState->syncProviderRunning;
- }
- }
-
- /*
- * If the sync provider is currently in execution and there's no
- * callback set, that means the sync provider is done executing,
- * so run the thaw scripts if we've received a "snapshot done"
- * event.
- */
- if (gBackupState->syncProviderRunning &&
- (gBackupState->snapshotDone ||
- gBackupState->syncProviderFailed ||
- gBackupState->clientAborted) &&
- gBackupState->callback == NULL) {
- gBackupState->syncProviderRunning = FALSE;
- gBackupState->pollPeriod = 100;
- if (gBackupState->syncProviderFailed || gBackupState->clientAborted) {
- finalize = !VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE_FAIL, NULL);
- } else {
- finalize = !VmBackupStartScripts(VMBACKUP_SCRIPT_THAW, NULL);
- }
- goto exit;
- }
-
- /*
- * If the sync provider is not running anymore, and either the operation
- * was aborted by the remote client or we don't have any callbacks to
- * process anymore, it must mean we're finished.
- */
- finalize = (!gBackupState->syncProviderRunning &&
- (gBackupState->callback == NULL || gBackupState->clientAborted));
-
-exit:
- if (finalize) {
- VmBackupFinalize();
- } else {
- gBackupState->forceRequeue = FALSE;
- VMBACKUP_ENQUEUE_EVENT();
- }
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupEnableSync --
- *
- * Calls the sync provider's start function.
- *
- * Result
- * Whether the sync provider call succeeded.
- *
- * Side effects:
- * Depends on the sync provider.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupEnableSync(VmBackupState *state)
-{
- DebugOutput("*** %s\n", __FUNCTION__);
- ASSERT(state != NULL);
- if (!gSyncProvider->start(state, gSyncProvider->clientData)) {
- state->SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR,
- VMBACKUP_SYNC_ERROR,
- "Error when enabling the sync provider.");
- return FALSE;
- }
-
- state->syncProviderRunning = TRUE;
- return TRUE;
-}
-
-
-/* RpcIn callbacks. */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupStart --
- *
- * Handler for the "vmbackup.start" message. Starts the "freeze" scripts
- * unless there's another backup operation going on or some other
- * unexpected error occurs.
- *
- * Result
- * TRUE, unless an error occurs.
- *
- * Side effects:
- * Depends on what the scripts do.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-VmBackupStart(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- size_t argsSize, // IN
- void *clientData) // IN
-{
- DebugOutput("*** %s\n", __FUNCTION__);
- if (gBackupState != NULL) {
- return RpcIn_SetRetVals(result,
- resultLen,
- "Backup operation already in progress.",
- FALSE);
- }
-
- gBackupState = Util_SafeMalloc(sizeof *gBackupState);
- memset(gBackupState, 0, sizeof *gBackupState);
-
- gBackupState->SendEvent = VmBackupSendEvent;
- gBackupState->pollPeriod = 100;
- gBackupState->loggingEnabled = gLoggingEnabled;
-
- if (argsSize > 0) {
- int generateManifests = 0;
- int index = 0;
-
- if (StrUtil_GetNextIntToken(&generateManifests, &index, args, " ")) {
- gBackupState->generateManifests = generateManifests;
- }
-
- if (args[index] != '\0') {
- gBackupState->volumes = Util_SafeStrdup(args + index);
- }
- }
-
- gBackupState->configDir = GuestApp_GetConfPath();
- if (gBackupState->configDir == NULL) {
- free(gBackupState);
- gBackupState = NULL;
- return RpcIn_SetRetVals(result,
- resultLen,
- "Error getting configuration directory.",
- FALSE);
- }
-
- gBackupState->SendEvent(VMBACKUP_EVENT_RESET, VMBACKUP_SUCCESS, "");
-
- if (!VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE, VmBackupEnableSync)) {
- free(gBackupState);
- gBackupState = NULL;
- return RpcIn_SetRetVals(result,
- resultLen,
- "Error initializing backup.",
- FALSE);
- }
-
- VMBACKUP_ENQUEUE_EVENT();
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupAbort --
- *
- * Aborts the current operation if one is active, and stops the backup
- * process. If the sync provider has been activated, tell it to abort
- * the ongoing operation.
- *
- * Result
- * TRUE
- *
- * Side effects:
- * Possibly many.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-VmBackupAbort(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- size_t argsSize, // IN
- void *clientData) // IN
-{
- DebugOutput("*** %s\n", __FUNCTION__);
- if (gBackupState != NULL) {
-
- if (gBackupState->currentOp != NULL) {
- VmBackup_Cancel(gBackupState->currentOp);
- VmBackup_Release(gBackupState->currentOp);
- gBackupState->currentOp = NULL;
- }
-
- if (gBackupState->syncProviderRunning) {
- gSyncProvider->abort(gBackupState, gSyncProvider->clientData);
- }
-
- gBackupState->clientAborted = TRUE;
- gBackupState->SendEvent(VMBACKUP_EVENT_REQUESTOR_ABORT,
- VMBACKUP_REMOTE_ABORT,
- "Remote abort.");
-
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
- } else {
- return RpcIn_SetRetVals(result, resultLen,
- "Error: no backup in progress", FALSE);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupSnapshotDone --
- *
- * Sets the flag that says it's OK to disable the sync driver.
- *
- * Result
- * TRUE
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-VmBackupSnapshotDone(char const **result, // OUT
- size_t *resultLen, // OUT
- const char *name, // IN
- const char *args, // IN
- size_t argsSize, // IN
- void *clientData) // IN
-{
- DebugOutput("*** %s\n", __FUNCTION__);
- if (gBackupState != NULL) {
- if (!gSyncProvider->snapshotDone(gBackupState, gSyncProvider->clientData)) {
- gBackupState->syncProviderFailed = TRUE;
- gBackupState->SendEvent(VMBACKUP_EVENT_REQUESTOR_ERROR,
- VMBACKUP_SYNC_ERROR,
- "Error when notifying the sync provider.");
- } else {
- gBackupState->snapshotDone = TRUE;
- }
- return RpcIn_SetRetVals(result, resultLen, "", TRUE);
- } else {
- return RpcIn_SetRetVals(result, resultLen,
- "Error: no backup in progress", FALSE);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackup_Init --
- *
- * Registers the RpcIn callbacks for the backup protocol.
- *
- * Result
- * TRUE.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-VmBackup_Init(RpcIn *rpcin, // IN
- DblLnkLst_Links *eventQueue, // IN
- VmBackupSyncProvider *provider, // IN
- Bool loggingEnabled) // IN
-{
- DebugOutput("*** %s\n", __FUNCTION__);
- ASSERT(gEventQueue == NULL);
- ASSERT(eventQueue != NULL);
- ASSERT(provider != NULL);
- ASSERT(provider->start != NULL);
- ASSERT(provider->abort != NULL);
- ASSERT(provider->snapshotDone != NULL);
- ASSERT(provider->release != NULL);
-
- gLoggingEnabled = loggingEnabled;
- RpcIn_RegisterCallback(rpcin,
- VMBACKUP_PROTOCOL_START,
- VmBackupStart,
- NULL);
- RpcIn_RegisterCallback(rpcin,
- VMBACKUP_PROTOCOL_ABORT,
- VmBackupAbort,
- NULL);
- RpcIn_RegisterCallback(rpcin,
- VMBACKUP_PROTOCOL_SNAPSHOT_DONE,
- VmBackupSnapshotDone,
- NULL);
- gEventQueue = eventQueue;
- gSyncProvider = provider;
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackup_Shutdown --
- *
- * Unregisters the RpcIn callbacks.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-VmBackup_Shutdown(RpcIn *rpcin)
-{
- DebugOutput("*** %s\n", __FUNCTION__);
- if (gBackupState != NULL) {
- VmBackupFinalize();
- }
-
- gSyncProvider->release(gSyncProvider);
- gSyncProvider = NULL;
-
- RpcIn_UnregisterCallback(rpcin, VMBACKUP_PROTOCOL_START);
- RpcIn_UnregisterCallback(rpcin, VMBACKUP_PROTOCOL_ABORT);
- RpcIn_UnregisterCallback(rpcin, VMBACKUP_PROTOCOL_SNAPSHOT_DONE);
- gEventQueue = NULL;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DebugOutput --
- *
- * Prints the given message using OutputDebugString in debug builds.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-DebugOutput(const char *fmt, ...)
-{
- if (gLoggingEnabled) {
- char *str;
- va_list args;
-
- va_start(args, fmt);
- str = Str_Vasprintf(NULL, fmt, args);
- va_end(args);
- if (str != NULL) {
-#if defined _WIN32
- OutputDebugString(str);
-#else
- fprintf(stderr, "%s", str);
-#endif
- free(str);
- }
- }
-}
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * syncDriverOps.c --
- *
- * Implements the sync driver provider for the backup state machine.
- */
-
-#include "vmBackup.h"
-
-#include "conf.h"
-#include "debug.h"
-#include "dynbuf.h"
-#include "file.h"
-#include "procMgr.h"
-#include "syncDriver.h"
-#include "util.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#include <process.h>
-#endif
-
-typedef struct VmBackupDriverOp {
- VmBackupOp callbacks;
- const char *volumes;
- Bool freeze;
- Bool canceled;
- SyncDriverHandle syncHandle;
-} VmBackupDriverOp;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupDriverOpQuery --
- *
- * Checks the status of the app that is enabling or disabling the
- * sync driver.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static VmBackupOpStatus
-VmBackupDriverOpQuery(VmBackupOp *_op) // IN
-{
- VmBackupDriverOp *op = (VmBackupDriverOp *) _op;
- VmBackupOpStatus ret;
-
- SyncDriverStatus st;
-
- st = SyncDriver_QueryStatus(op->syncHandle, 0);
- Debug("SyncDriver status: %d\n", st);
-
- switch(st) {
- case SYNCDRIVER_BUSY:
- ret = VMBACKUP_STATUS_PENDING;
- break;
-
- case SYNCDRIVER_IDLE:
- if (op->freeze && op->canceled) {
- SyncDriver_Thaw(op->syncHandle);
- }
- ret = (op->canceled) ? VMBACKUP_STATUS_CANCELED : VMBACKUP_STATUS_FINISHED;
- break;
-
- default:
- ret = VMBACKUP_STATUS_ERROR;
- break;
- }
-
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupDriverOpRelease --
- *
- * Cleans up data held by the state object.
- *
- * Result
- * The status of the app.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-VmBackupDriverOpRelease(VmBackupOp *_op) // IN
-{
- VmBackupDriverOp *op = (VmBackupDriverOp *) _op;
- if (!op->freeze) {
- SyncDriver_CloseHandle(&op->syncHandle);
- }
- free(op);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupDriverOpCancel --
- *
- * Cancel an ongoing sync driver operation. This doesn't actually
- * cancel the operation, but rather waits for it to finish, since
- * just killing the worker thread might have undesired side effects.
- * This will not cancel thaw operations.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-VmBackupDriverOpCancel(VmBackupOp *_op) // IN
-{
- VmBackupDriverOp *op = (VmBackupDriverOp *) _op;
- op->canceled = TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupNewDriverOp --
- *
- * Enables or disables the sync driver. Note: "volumes" is not copied,
- * to avoid unnecessary waste of memory, since it's kept in the global
- * backup state structure.
- *
- * Result
- * A state object, unless some error occurs.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static VmBackupDriverOp *
-VmBackupNewDriverOp(Bool freeze, // IN
- SyncDriverHandle handle, // IN
- const char *volumes) // IN
-{
- VmBackupDriverOp *op = NULL;
-
- op = Util_SafeMalloc(sizeof *op);
- memset(op, 0, sizeof *op);
-
- op->callbacks.queryFn = VmBackupDriverOpQuery;
- op->callbacks.cancelFn = VmBackupDriverOpCancel;
- op->callbacks.releaseFn = VmBackupDriverOpRelease;
- op->freeze = freeze;
- op->volumes = volumes;
-
- if (freeze && !SyncDriver_Freeze(op->volumes, &handle)) {
- Debug("Error freezing filesystems.\n");
- free(op);
- op = NULL;
- } else if (!freeze && !SyncDriver_Thaw(handle)) {
- Debug("Error thawing filesystems.\n");
- free(op);
- op = NULL;
- } else {
- op->syncHandle = handle;
- }
- return op;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupSyncDriverReadyForSnapshot --
- *
- * Sends an event to the VMX indicating that the guest is ready for a
- * snapshot to be taken (i.e., scripts have run and sync driver is
- * enabled).
- *
- * Result
- * TRUE, unless sending the message fails.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupSyncDriverReadyForSnapshot(VmBackupState *state)
-{
- Debug("*** %s\n", __FUNCTION__);
- return state->SendEvent(VMBACKUP_EVENT_SNAPSHOT_COMMIT, 0, "");
-}
-
-
-/* Sync provider implementation. */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupSyncDriverStart --
- *
- * Starts an asynchronous operation to enable the sync driver.
- *
- * Result
- * TRUE, unless an error occurs.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupSyncDriverStart(VmBackupState *state,
- void *clientData)
-{
- VmBackupDriverOp *op;
-
- Debug("*** %s\n", __FUNCTION__);
- op = VmBackupNewDriverOp(TRUE,
- (SyncDriverHandle) state->clientData,
- state->volumes);
-
- if (op != NULL) {
- state->clientData = (intptr_t) op->syncHandle;
- }
-
- return VmBackup_SetCurrentOp(state,
- (VmBackupOp *) op,
- VmBackupSyncDriverReadyForSnapshot,
- __FUNCTION__);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupSyncDriverAbort --
- *
- * Does nothing.
- *
- * Result
- * TRUE.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupSyncDriverAbort(VmBackupState *state,
- void *clientData)
-{
- Debug("*** %s\n", __FUNCTION__);
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupSyncDriverSnapshotDone --
- *
- * Starts an asynchronous operation to disable the sync driver.
- *
- * Result
- * TRUE, unless an error occurs.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-VmBackupSyncDriverSnapshotDone(VmBackupState *state,
- void *clientData)
-{
- VmBackupDriverOp *op;
-
- Debug("*** %s\n", __FUNCTION__);
-
- op = VmBackupNewDriverOp(FALSE,
- (SyncDriverHandle) state->clientData,
- NULL);
-
- return VmBackup_SetCurrentOp(state, (VmBackupOp *) op, NULL, __FUNCTION__);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackupSyncDriverRelease --
- *
- * Frees the given pointer.
- *
- * Result
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-VmBackupSyncDriverRelease(struct VmBackupSyncProvider *provider)
-{
- free(provider);
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VmBackup_NewSyncDriverProvider --
- *
- * Returns a new VmBackupSyncProvider that will enable the sync driver
- * as part of the "sync" operation of a backup.
- *
- * Result
- * NULL on error.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-VmBackupSyncProvider *
-VmBackup_NewSyncDriverProvider(void)
-{
- VmBackupSyncProvider *provider;
-
- if (!SyncDriver_Init()) {
- Debug("Error initializing the sync driver.\n");
- return NULL;
- }
-
- provider = Util_SafeMalloc(sizeof *provider);
- provider->start = VmBackupSyncDriverStart;
- provider->abort = VmBackupSyncDriverAbort;
- provider->snapshotDone = VmBackupSyncDriverSnapshotDone;
- provider->release = VmBackupSyncDriverRelease;
- provider->clientData = NULL;
-
- return provider;
-}
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * vmBackupInt.h --
- *
- * Internal definitions used by the vmbackup code.
- */
-
-#ifndef _VMBACKUPINT_H_
-#define _VMBACKUPINT_H_
-
-typedef enum {
- VMBACKUP_SCRIPT_FREEZE,
- VMBACKUP_SCRIPT_FREEZE_FAIL,
- VMBACKUP_SCRIPT_THAW
-} VmBackupScriptType;
-
-
-VmBackupOp *
-VmBackupNewScriptOp(VmBackupScriptType freeze,
- VmBackupState *state);
-
-#endif /* _VMBACKUPINT_H_*/
-
AM_CFLAGS += -I$(top_builddir)/include
libguestlib_la_LIBADD =
-libguestlib_la_LIBADD += ../lib/rpcOut/libRpcOut.la
-libguestlib_la_LIBADD += ../lib/string/libString.la
-libguestlib_la_LIBADD += ../lib/stubs/libStubs.la
-# In the absence of the linker options --start-group and --end-group (which can't
-# be put in LDADD), we need to bring the following libraries out of the alphebetical
-# order so their symbols are properly resolved.
-libguestlib_la_LIBADD += ../lib/message/libMessage.la
-libguestlib_la_LIBADD += ../lib/backdoor/libBackdoor.la
-libguestlib_la_LIBADD += ../lib/guestRpc/libGuestRpc.la
+libguestlib_la_LIBADD += @VMTOOLS_LIBS@
libguestlib_la_SOURCES =
libguestlib_la_SOURCES += vmGuestLib.c
-libguestlib_la_SOURCES += vmGuestLibPanic.c
libguestlib_la_LDFLAGS =
# We require GCC, so we're fine passing compiler-specific flags.
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * vmGuestLib.c --
- *
- * DLL wrapper for vmGuestLib, compiles the bits of libs in
- * bora-vmsoft needed for GuestLib.
- */
-
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#include <stdarg.h>
-#include <stdio.h>
-
-#include "vmware.h"
-#include "str.h"
-
-#include "vmguestlib_version.h"
-#include "embed_version.h"
-VM_EMBED_VERSION(VMGUESTLIB_VERSION_STRING);
-
-#ifdef _WIN32
-/*
- *-----------------------------------------------------------------------------
- *
- * DllMain --
- *
- * Entry point for the DLL.
- *
- * Results:
- * TRUE
- *
- * Side effects:
- * DLL init.
- *
- *-----------------------------------------------------------------------------
- */
-
-BOOL WINAPI
-DllMain(HINSTANCE hInstance,
- DWORD dwReason,
- LPVOID lpReserved)
-{
- if (dwReason == DLL_PROCESS_ATTACH) {
- /* Any one time initialization should go here. */
- } else if (dwReason == DLL_PROCESS_DETACH) {
- }
-
- return TRUE;
-}
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Panic --
- *
- * Panic. Apps have to implement this for themselves.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Death.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Panic(const char *fmt, ...) // IN
-{
- va_list args;
- char buffer[1024];
- volatile char *p = NULL;
-
- va_start(args, fmt);
- Str_Vsnprintf(buffer, sizeof buffer, fmt, args);
- va_end(args);
-
- printf("PANIC: %s", buffer);
-
- /* force segfault */
- buffer[0] = *p;
- while (1) ; // avoid compiler warning
-}
libvmtools_la_LIBADD += ../lib/err/libErr.la
libvmtools_la_LIBADD += ../lib/file/libFile.la
libvmtools_la_LIBADD += ../lib/guestApp/libGuestApp.la
-libvmtools_la_LIBADD += ../lib/guestInfo/libGuestInfoCS.la
+libvmtools_la_LIBADD += ../lib/guestInfo/libGuestInfo.la
libvmtools_la_LIBADD += ../lib/guestRpc/libGuestRpc.la
libvmtools_la_LIBADD += ../lib/hgfs/libHgfs.la
libvmtools_la_LIBADD += ../lib/message/libMessage.la
{ CONFNAME_MAX_WIPERSIZE, "vmsvc", CONFNAME_MAX_WIPERSIZE, CFG_INTEGER, NULL },
{ CONFNAME_DISABLEQUERYDISKINFO, "guestinfo", CONFNAME_DISABLEQUERYDISKINFO, CFG_BOOLEAN, NULL },
{ CONFNAME_DISABLETOOLSVERSION, "vmsvc", CONFNAME_DISABLETOOLSVERSION, CFG_BOOLEAN, NULL },
-#if !defined(_WIN32)
- { CONFNAME_HALT, "vmsvc", CONFNAME_HALT, CFG_STRING, NULL },
- { CONFNAME_REBOOT, "vmsvc", CONFNAME_REBOOT, CFG_STRING, NULL },
- /* HGFS options. */
- { CONFNAME_MOUNT_POINT, "hgfs", CONFNAME_MOUNT_POINT, CFG_STRING, NULL },
-#else
+#if defined(_WIN32)
/* Tray options. */
{ CONFNAME_SHOW_WIRELESS_ICON, "vmtray", CONFNAME_SHOW_WIRELESS_ICON, CFG_BOOLEAN, NULL },
#endif
modulesrc = $(top_srcdir)/modules
$(MODULES):
- $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm $(EXTRA_ARGS) \
+ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \
+ OVT_SOURCE_DIR=$(abs_top_srcdir) $(EXTRA_ARGS) \
-C "$(modulesrc)/$(MODULES_OS)/$@"
if FREEBSD_CUSTOM_SYSDIR
{
struct DblLnkLst_Links *curr;
- /* XXX The following is only temporary. */
-#ifdef __FreeBSD__
+ /*
+ * On FreeBSD we have a mechanism to assert (but not simply check)
+ * that a lock is held. Since semantic is different (panic that
+ * happens if assertion fails can not be suppressed) we are using
+ * different name.
+ */
+#ifdef os_assert_rwlock_held
os_assert_rwlock_held(&blockedFilesLock);
#else
ASSERT(os_rwlock_held(&blockedFilesLock));
#elif defined(__APPLE__) && defined(KERNEL)
+#include "availabilityMacOS.h"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// The Mac OS 10.5 kernel SDK defines va_copy in stdarg.h.
+#include <stdarg.h>
+#else
/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
+ * The Mac OS 10.4 kernel SDK needs va_copy. Based on inspection of
+ * stdarg.h from the MacOSX10.4u.sdk kernel framework, this should
+ * work.
*/
-
#define va_copy(dest, src) ((dest) = (src))
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#elif defined(__GNUC__) && (__GNUC__ < 3)
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
# include <sys/param.h>
#endif
-#define VMBLOCK_FS_NAME "vmblock"
+
+/*
+ * FUSE definitions. They are supposed to be used by userspace code and
+ * therefore not guarded by ARCH defines since FUSE can potentially
+ * be used on different operating systems.
+ */
+
+#define VMBLOCK_FUSE_ADD_FILEBLOCK 'a'
+#define VMBLOCK_FUSE_DEL_FILEBLOCK 'd'
+#ifdef VMX86_DEVEL
+# define VMBLOCK_FUSE_LIST_FILEBLOCKS 'l'
+#endif /* VMX86_DEVEL */
+
+/*
+ * If you try 'read'-ing from file descriptor vmblock-fuse is supposed
+ * to respond with the following. It is used to check whether we deal
+ * with FUSE or in-kernel implementation.
+ */
+#define VMBLOCK_FUSE_READ_RESPONSE "I am VMBLOCK-FUSE"
+
+#define VMBLOCK_FUSE_FS_NAME "fuse.vmware-vmblock"
+#define VMBLOCK_FUSE_MOUNT_POINT "/tmp/vmblock-fuse"
+#define VMBLOCK_FUSE_CTRL_MNTPNT "blockdir"
+#define VMBLOCK_FUSE_FS_ROOT VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_CTRL_MNTPNT
+#define VMBLOCK_FUSE_DEVICE_NAME "dev"
+#define VMBLOCK_FUSE_DEVICE VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_DEVICE_NAME
+#define VMBLOCK_FUSE_DEVICE_MODE O_RDWR
/* Commands for the control half of vmblock driver */
#if defined(vmblock_fuse)
+/* These definitions are for vmblock-fuse module itself */
# include <unistd.h>
# include <limits.h>
# include <string.h>
# include <errno.h>
# include "vm_basic_types.h"
-# define VMBLOCK_ADD_FILEBLOCK 'a'
-# define VMBLOCK_DEL_FILEBLOCK 'd'
+# define VMBLOCK_ADD_FILEBLOCK VMBLOCK_FUSE_ADD_FILEBLOCK
+# define VMBLOCK_DEL_FILEBLOCK VMBLOCK_FUSE_DEL_FILEBLOCK
# ifdef VMX86_DEVEL
-# define VMBLOCK_LIST_FILEBLOCKS 'l'
+# define VMBLOCK_LIST_FILEBLOCKS VMBLOCK_FUSE_LIST_FILEBLOCKS
# endif /* VMX86_DEVEL */
/*
* Some of the following names don't actually make much sense on their own.
* They're used for consistency with the other ports. See the file header for
* explanations of what they're used for.
*/
-# define VMBLOCK_DEVICE_NAME "dev"
-# define VMBLOCK_CONTROL_MOUNTPOINT "blockdir"
-# define VMBLOCK_DEVICE "/tmp/vmblock/" VMBLOCK_DEVICE_NAME
-# define VMBLOCK_DEVICE_MODE O_WRONLY
-# define VMBLOCK_MOUNT_POINT "/tmp/vmblock/" VMBLOCK_CONTROL_MOUNTPOINT
-static INLINE ssize_t
- VMBLOCK_CONTROL(int fd, char op, const char *path)
-{
- /*
- * buffer needs room for an operation character and a string with max length
- * PATH_MAX - 1.
- */
-
- char buffer[PATH_MAX];
- size_t pathLength;
-
- pathLength = strlen(path);
- if (pathLength >= PATH_MAX) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- buffer[0] = op;
- memcpy(buffer + 1, path, pathLength);
-
- /*
- * The lseek is only to prevent the file pointer from overflowing;
- * vmblock-fuse ignores the file pointer / offset. Overflowing the file
- * pointer causes write to fail:
- * http://article.gmane.org/gmane.comp.file-systems.fuse.devel/6648
- * There's also a race condition here where many threads all calling
- * VMBLOCK_CONTROL at the same time could have all their seeks executed one
- * after the other, followed by all the writes. Again, it's not a problem
- * unless the file pointer overflows which is very unlikely with 32 bit
- * offsets and practically impossible with 64 bit offsets.
- */
-
- if (lseek(fd, 0, SEEK_SET) < 0) {
- return -1;
- }
- if (write(fd, buffer, pathLength + 1) < 0) {
- return -1;
- }
- return 0;
-}
+# define VMBLOCK_FS_NAME VMBLOCK_FUSE_FS_NAME
+# define VMBLOCK_DEVICE_NAME VMBLOCK_FUSE_DEVICE_NAME
+# define VMBLOCK_CONTROL_MOUNTPOINT VMBLOCK_FUSE_CTRL_MNTPNT
+# define VMBLOCK_DEVICE VMBLOCK_FUSE_DEVICE
+# define VMBLOCK_DEVICE_MODE VMBLOCK_FUSE_DEVICE_MODE
+# define VMBLOCK_MOUNT_POINT VMBLOCK_FUSE_MOUNT_POINT
#elif defined(linux)
-# define VMBLOCK_ADD_FILEBLOCK 98
-# define VMBLOCK_DEL_FILEBLOCK 99
+# define VMBLOCK_ADD_FILEBLOCK 98
+# define VMBLOCK_DEL_FILEBLOCK 99
# ifdef VMX86_DEVEL
-# define VMBLOCK_LIST_FILEBLOCKS 100
+# define VMBLOCK_LIST_FILEBLOCKS 100
# endif
-# define VMBLOCK_CONTROL_DIRNAME VMBLOCK_FS_NAME
-# define VMBLOCK_CONTROL_DEVNAME "dev"
-# define VMBLOCK_CONTROL_MOUNTPOINT "mountPoint"
-# define VMBLOCK_CONTROL_PROC_DIRNAME "fs/" VMBLOCK_CONTROL_DIRNAME
+# define VMBLOCK_FS_NAME "vmblock"
+# define VMBLOCK_CONTROL_DIRNAME VMBLOCK_FS_NAME
+# define VMBLOCK_CONTROL_DEVNAME "dev"
+# define VMBLOCK_CONTROL_MOUNTPOINT "mountPoint"
+# define VMBLOCK_CONTROL_PROC_DIRNAME "fs/" VMBLOCK_CONTROL_DIRNAME
# define VMBLOCK_MOUNT_POINT "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \
"/" VMBLOCK_CONTROL_MOUNTPOINT
+# define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \
"/" VMBLOCK_CONTROL_DEVNAME
# define VMBLOCK_DEVICE_MODE O_WRONLY
-# define VMBLOCK_CONTROL(fd, op, path) write(fd, path, op)
#elif defined(sun) || defined(__FreeBSD__)
+# define VMBLOCK_FS_NAME "vmblock"
# define VMBLOCK_MOUNT_POINT "/var/run/" VMBLOCK_FS_NAME
+# define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE_MODE O_RDONLY
# if defined(sun) /* if (sun) { */
# ifdef VMX86_DEVEL
# define VMBLOCK_LIST_FILEBLOCKS _IO('v', 3)
# endif
-# define VMBLOCK_CONTROL(fd, op, path) ioctl(fd, op, path)
# elif defined(__FreeBSD__) /* } else if (FreeBSD) { */
/*
# define VMBLOCK_LIST_FILEBLOCKS _IO('Z', 3)
# define VMBLOCK_PURGE_FILEBLOCKS _IO('Z', 4)
# endif
- /*
- * FreeBSD's ioctl data parameters must be of fixed size. Guarantee a safe
- * buffer of size MAXPATHLEN by copying the user's string to one of our own.
- */
-# define VMBLOCK_CONTROL(fd, cmd, path) \
-({ \
- char tpath[MAXPATHLEN]; \
- if (path != NULL) { \
- strlcpy(tpath, path, MAXPATHLEN); \
- } \
- ioctl((fd), (cmd), tpath); \
-})
+
# endif /* } */
#else
# error "Unknown platform for vmblock."
#elif defined(__APPLE__) && defined(KERNEL)
+#include "availabilityMacOS.h"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// The Mac OS 10.5 kernel SDK defines va_copy in stdarg.h.
+#include <stdarg.h>
+#else
/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
+ * The Mac OS 10.4 kernel SDK needs va_copy. Based on inspection of
+ * stdarg.h from the MacOSX10.4u.sdk kernel framework, this should
+ * work.
*/
-
#define va_copy(dest, src) ((dest) = (src))
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#elif defined(__GNUC__) && (__GNUC__ < 3)
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
FLAGDEFA( 1, ECX, COMMON, 3, 1, MWAIT, NO, MASK, 0, FALSE, MWAIT) \
FLAGDEFA( 1, ECX, INTEL, 4, 1, DSCPL, NO, MASK, 0, FALSE, DSCPL) \
FLAGDEFA( 1, ECX, INTEL, 5, 1, VMX, NO, MASK, 0, FALSE, VMX) \
-FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
+FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
FLAGDEF( 1, ECX, INTEL, 7, 1, EST, NO, MASK, 0, FALSE) \
FLAGDEF( 1, ECX, INTEL, 8, 1, TM2, NO, MASK, 0, FALSE) \
FLAGDEFA( 1, ECX, COMMON, 9, 1, SSSE3, YES, HOST, 0, TRUE, SSSE3) \
FLAGDEF( 81, EDX, AMD, 23, 1, MMX, YES, HOST, 0, TRUE) \
FLAGDEF( 81, EDX, AMD, 24, 1, FXSAVE, YES, HOST, 0, TRUE) \
FLAGDEFA( 81, EDX, AMD, 25, 1, FFXSR, YES, HOST, 0, FALSE, FFXSR) \
-FLAGDEF( 81, EDX, AMD, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
+FLAGDEF( 81, EDX, COMMON, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
FLAGDEFA( 81, EDX, COMMON, 27, 1, RDTSCP, YES, HOST, 0, TRUE, RDTSCP) \
FLAGDEFA( 81, EDX, COMMON, 29, 1, LM, YES, TEST, 1, FALSE, LM) \
FLAGDEFA( 81, EDX, AMD, 30, 1, 3DNOWPLUS, YES, HOST, 0, TRUE, 3DNOWPLUS) \
FLAGDEF( 8A, EDX, AMD, 3, 1, SVM_NRIP, NO, MASK, 0, FALSE) \
FIELDDEF( 8A, EDX, AMD, 4, 28, SVMEDX_RSVD, NO, MASK, 0, FALSE)
+
#define CPUID_FIELD_DATA \
CPUID_FIELD_DATA_LEVEL_0 \
CPUID_FIELD_DATA_LEVEL_1 \
CPUID_FIELD_DATA_LEVEL_81 \
CPUID_FIELD_DATA_LEVEL_8x
+
/*
* Define all field and flag values as an enum. The result is a full
* set of values taken from the table above in the form:
* macros/functions for reading cpuid fields.
*/
+#define CPUID_FAMILY_EXTENDED 15
+
/* Effective Intel CPU Families */
#define CPUID_FAMILY_486 4
#define CPUID_FAMILY_P5 5
#define CPUID_FAMILY_K8 15
#define CPUID_FAMILY_K8L 16
#define CPUID_FAMILY_K8MOBILE 17
-#define CPUID_FAMILY_EXTENDED 15
/* Intel model information */
#define CPUID_MODEL_PPRO 1
#define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown
#define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville
#define CPUID_MODEL_CORE_1D 0x1d // Dunnington
-#define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield
#define CPUID_MODEL_PIII_07 7
#define CPUID_MODEL_PIII_08 8
CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1.
{
/* Assumes the CPU manufacturer is Intel. */
+ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
+
return CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1A ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1E);
+ (
+ effectiveModel == CPUID_MODEL_NEHALEM_1A);
}
static INLINE Bool
#elif defined(__APPLE__) && defined(KERNEL)
+#include "availabilityMacOS.h"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// The Mac OS 10.5 kernel SDK defines va_copy in stdarg.h.
+#include <stdarg.h>
+#else
/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
+ * The Mac OS 10.4 kernel SDK needs va_copy. Based on inspection of
+ * stdarg.h from the MacOSX10.4u.sdk kernel framework, this should
+ * work.
*/
-
#define va_copy(dest, src) ((dest) = (src))
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#elif defined(__GNUC__) && (__GNUC__ < 3)
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
+#define PCI_DEVICE_ID_VMWARE_VMXWIFI 0x07B8
#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
/* The hypervisor device might grow. Please leave room
PACKAGE_NAME=open-vm-tools
-PACKAGE_VERSION=2009.03.18
+PACKAGE_VERSION=2009.04.23
MAKE[0]="make -C pvscsi VM_UNAME=\$kernelver; \
make -C vmblock VM_UNAME=\$kernelver; \
make -C vmhgfs VM_UNAME=\$kernelver; \
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := pvscsi
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#### VMware pvscsi Makefile to be distributed externally
####
-INCLUDE := -I.
+INCLUDE += -I.
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_defs.h --
- *
- * Standard macros for VMware source code.
- */
-
-#ifndef _VM_BASIC_DEFS_H_
-#define _VM_BASIC_DEFS_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-#include "vm_basic_types.h" // For INLINE.
-
-/* Checks for FreeBSD, filtering out VMKERNEL. */
-#define __IS_FREEBSD__ (!defined(VMKERNEL) && defined(__FreeBSD__))
-#define __IS_FREEBSD_VER__(ver) (__IS_FREEBSD__ && __FreeBSD_version >= (ver))
-
-#if defined _WIN32 && defined USERLEVEL
- #include <stddef.h> /*
- * We re-define offsetof macro from stddef, make
- * sure that its already defined before we do it
- */
- #include <windows.h> // for Sleep() and LOWORD() etc.
-#endif
-
-
-/*
- * Simple macros
- */
-
-#if (defined __APPLE__ || defined __FreeBSD__) && \
- (!defined KERNEL && !defined _KERNEL && !defined VMKERNEL && !defined __KERNEL__)
-# include <stddef.h>
-#else
-// XXX the _WIN32 one matches that of VC++, to prevent redefinition warning
-// XXX the other one matches that of gcc3.3.3/glibc2.2.4 to prevent redefinition warnings
-#ifndef offsetof
-#ifdef _WIN32
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-#endif
-#endif // __APPLE__
-
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(a) (sizeof (a) / sizeof *(a))
-#endif
-
-#ifndef MIN
-#define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
-#endif
-
-/* The Solaris 9 cross-compiler complains about these not being used */
-#ifndef sun
-static INLINE int
-Min(int a, int b)
-{
- return a < b ? a : b;
-}
-#endif
-
-#ifndef MAX
-#define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
-#endif
-
-#ifndef sun
-static INLINE int
-Max(int a, int b)
-{
- return a > b ? a : b;
-}
-#endif
-
-#define ROUNDUP(x,y) (((x) + (y) - 1) / (y) * (y))
-#define ROUNDDOWN(x,y) ((x) / (y) * (y))
-#define ROUNDUPBITS(x, bits) (((uintptr_t) (x) + MASK(bits)) & ~MASK(bits))
-#define ROUNDDOWNBITS(x, bits) ((uintptr_t) (x) & ~MASK(bits))
-#define CEILING(x, y) (((x) + (y) - 1) / (y))
-#if defined __APPLE__
-#include <machine/param.h>
-#undef MASK
-#endif
-#define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */
-#define DWORD_ALIGN(x) ((((x)+3) >> 2) << 2)
-#define QWORD_ALIGN(x) ((((x)+4) >> 3) << 3)
-
-#define IMPLIES(a,b) (!(a) || (b))
-
-/*
- * Not everybody (e.g., the monitor) has NULL
- */
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *)0)
-#endif
-#endif
-
-
-/*
- * Token concatenation
- *
- * The C preprocessor doesn't prescan arguments when they are
- * concatenated or stringified. So we need extra levels of
- * indirection to convince the preprocessor to expand its
- * arguments.
- */
-
-#define CONC(x, y) x##y
-#define XCONC(x, y) CONC(x, y)
-#define XXCONC(x, y) XCONC(x, y)
-#define MAKESTR(x) #x
-#define XSTR(x) MAKESTR(x)
-
-
-/*
- * Page operations
- *
- * It has been suggested that these definitions belong elsewhere
- * (like x86types.h). However, I deem them common enough
- * (since even regular user-level programs may want to do
- * page-based memory manipulation) to be here.
- * -- edward
- */
-
-#ifndef PAGE_SHIFT // {
-#if defined VM_I386
- #define PAGE_SHIFT 12
-#elif defined __APPLE__
- #define PAGE_SHIFT 12
-#else
- #error
-#endif
-#endif // }
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE (1<<PAGE_SHIFT)
-#endif
-
-#ifndef PAGE_MASK
-#define PAGE_MASK (PAGE_SIZE - 1)
-#endif
-
-#ifndef PAGE_OFFSET
-#define PAGE_OFFSET(_addr) ((uintptr_t)(_addr)&(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGE_BASE
-#define VM_PAGE_BASE(_addr) ((_addr)&~(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGES_SPANNED
-#define VM_PAGES_SPANNED(_addr, _size) \
- ((((_addr) & (PAGE_SIZE - 1)) + (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
-#endif
-
-#ifndef BYTES_2_PAGES
-#define BYTES_2_PAGES(_nbytes) ((_nbytes) >> PAGE_SHIFT)
-#endif
-
-#ifndef PAGES_2_BYTES
-#define PAGES_2_BYTES(_npages) (((uint64)(_npages)) << PAGE_SHIFT)
-#endif
-
-#ifndef MBYTES_2_PAGES
-#define MBYTES_2_PAGES(_nbytes) ((_nbytes) << (20 - PAGE_SHIFT))
-#endif
-
-#ifndef PAGES_2_MBYTES
-#define PAGES_2_MBYTES(_npages) ((_npages) >> (20 - PAGE_SHIFT))
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SHIFT
-#define VM_PAE_LARGE_PAGE_SHIFT 21
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SIZE
-#define VM_PAE_LARGE_PAGE_SIZE (1 << VM_PAE_LARGE_PAGE_SHIFT)
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_MASK
-#define VM_PAE_LARGE_PAGE_MASK (VM_PAE_LARGE_PAGE_SIZE - 1)
-#endif
-
-#ifndef VM_PAE_LARGE_2_SMALL_PAGES
-#define VM_PAE_LARGE_2_SMALL_PAGES (BYTES_2_PAGES(VM_PAE_LARGE_PAGE_SIZE))
-#endif
-
-/*
- * Word operations
- */
-
-#ifndef LOWORD
-#define LOWORD(_dw) ((_dw) & 0xffff)
-#endif
-#ifndef HIWORD
-#define HIWORD(_dw) (((_dw) >> 16) & 0xffff)
-#endif
-
-#ifndef LOBYTE
-#define LOBYTE(_w) ((_w) & 0xff)
-#endif
-#ifndef HIBYTE
-#define HIBYTE(_w) (((_w) >> 8) & 0xff)
-#endif
-
-#define HIDWORD(_qw) ((uint32)((_qw) >> 32))
-#define LODWORD(_qw) ((uint32)(_qw))
-#define QWORD(_hi, _lo) ((((uint64)(_hi)) << 32) | ((uint32)(_lo)))
-
-
-/*
- * Deposit a field _src at _pos bits from the right,
- * with a length of _len, into the integer _target.
- */
-
-#define DEPOSIT_BITS(_src,_pos,_len,_target) { \
- unsigned mask = ((1 << _len) - 1); \
- unsigned shiftedmask = ((1 << _len) - 1) << _pos; \
- _target = (_target & ~shiftedmask) | ((_src & mask) << _pos); \
-}
-
-
-/*
- * Get return address.
- */
-
-#ifdef _MSC_VER
-#ifdef __cplusplus
-extern "C"
-#endif
-void *_ReturnAddress(void);
-#pragma intrinsic(_ReturnAddress)
-#define GetReturnAddress() _ReturnAddress()
-#elif __GNUC__
-#define GetReturnAddress() __builtin_return_address(0)
-#endif
-
-
-#ifdef __GNUC__
-#ifndef sun
-
-/*
- * Get the frame pointer. We use this assembly hack instead of
- * __builtin_frame_address() due to a bug introduced in gcc 4.1.1
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetFrameAddr(void)
-{
- uintptr_t bp;
-#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0))
- bp = (uintptr_t)__builtin_frame_address(0);
-#elif (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 3)
-# if defined(VMM64) || defined(VM_X86_64)
- __asm__ __volatile__("movq %%rbp, %0\n" : "=g" (bp));
-# else
- __asm__ __volatile__("movl %%ebp, %0\n" : "=g" (bp));
-# endif
-#else
- __asm__ __volatile__(
-#ifdef __linux__
- ".print \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
- ".abort"
-#else /* MacOS */
- ".abort \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
-#endif
- : "=g" (bp)
- );
-#endif
- return bp;
-}
-
-
-/*
- * Returns the frame pointer of the calling function.
- * Equivalent to __builtin_frame_address(1).
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetCallerFrameAddr(void)
-{
- return *(uintptr_t*)GetFrameAddr();
-}
-
-#endif // sun
-#endif // __GNUC__
-
-/*
- * Data prefetch was added in gcc 3.1.1
- * http://www.gnu.org/software/gcc/gcc-3.1/changes.html
- */
-#ifdef __GNUC__
-# if ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 1) || \
- (__GNUC__ == 3 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 1))
-# define PREFETCH_R(var) __builtin_prefetch((var), 0 /* read */, \
- 3 /* high temporal locality */)
-# define PREFETCH_W(var) __builtin_prefetch((var), 1 /* write */, \
- 3 /* high temporal locality */)
-# else
-# define PREFETCH_R(var) ((void)(var))
-# define PREFETCH_W(var) ((void)(var))
-# endif
-#endif /* __GNUC__ */
-
-
-#ifdef USERLEVEL // {
-
-/*
- * Note this might be a problem on NT b/c while sched_yield guarantees it
- * moves you to the end of your priority list, Sleep(0) offers no such
- * guarantee. Bummer. --Jeremy.
- */
-
-#if defined(N_PLAT_NLM)
-/* We do not have YIELD() as we do not need it yet... */
-#elif defined(_WIN32)
-# define YIELD() Sleep(0)
-#else
-# include <sched.h> // For sched_yield. Don't ask. --Jeremy.
-# define YIELD() sched_yield()
-#endif
-
-
-/*
- * Standardize some Posix names on Windows.
- */
-
-#ifdef _WIN32 // {
-
-#define snprintf _snprintf
-#define strtok_r strtok_s
-
-#if (_MSC_VER < 1500)
-#define vsnprintf _vsnprintf
-#endif
-
-typedef int uid_t;
-typedef int gid_t;
-
-static INLINE void
-sleep(unsigned int sec)
-{
- Sleep(sec * 1000);
-}
-
-static INLINE void
-usleep(unsigned long usec)
-{
- Sleep(CEILING(usec, 1000));
-}
-
-typedef int pid_t;
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-#define R_OK 4
-
-#endif // }
-
-/*
- * Macro for username comparison.
- */
-
-#ifdef _WIN32 // {
-#define USERCMP(x,y) Str_Strcasecmp(x,y)
-#else
-#define USERCMP(x,y) strcmp(x,y)
-#endif // }
-
-
-#endif // }
-
-#ifndef va_copy
-
-#ifdef _WIN32
-
-/*
- * Windows needs va_copy. This works for both 32 and 64-bit Windows
- * based on inspection of how varags.h from the Visual C CRTL is
- * implemented. (Future versions of the RTL may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__APPLE__) && defined(KERNEL)
-
-/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__GNUC__) && (__GNUC__ < 3)
-
-/*
- * Old versions of gcc recognize __va_copy, but not va_copy.
- */
-
-#define va_copy(dest, src) __va_copy(dest, src)
-
-#endif // _WIN32
-
-#endif // va_copy
-
-/*
- * This one is outside USERLEVEL because it's used by
- * files compiled into the Windows hgfs driver or the display
- * driver.
- */
-
-#ifdef _WIN32
-#define PATH_MAX 256
-#ifndef strcasecmp
-#define strcasecmp(_s1,_s2) _stricmp((_s1),(_s2))
-#endif
-#ifndef strncasecmp
-#define strncasecmp(_s1,_s2,_n) _strnicmp((_s1),(_s2),(_n))
-#endif
-#endif
-
-/*
- * Convenience macro for COMMUNITY_SOURCE
- */
-#undef EXCLUDE_COMMUNITY_SOURCE
-#ifdef COMMUNITY_SOURCE
- #define EXCLUDE_COMMUNITY_SOURCE(x)
-#else
- #define EXCLUDE_COMMUNITY_SOURCE(x) x
-#endif
-
-#undef COMMUNITY_SOURCE_INTEL_SECRET
-#if !defined(COMMUNITY_SOURCE) || defined(INTEL_SOURCE)
-/*
- * It's ok to include INTEL_SECRET source code for non-commsrc,
- * or for drops directed at Intel.
- */
- #define COMMUNITY_SOURCE_INTEL_SECRET
-#endif
-
-/*
- * Convenience macros and definitions. Can often be used instead of #ifdef.
- */
-
-#undef DEBUG_ONLY
-#undef SL_DEBUG_ONLY
-#undef VMX86_SL_DEBUG
-#ifdef VMX86_DEBUG
-#define vmx86_debug 1
-#define DEBUG_ONLY(x) x
-/*
- * Be very, very, very careful with SL_DEBUG. Pls ask ganesh or min before
- * using it.
- */
-#define VMX86_SL_DEBUG
-#define vmx86_sl_debug 1
-#define SL_DEBUG_ONLY(x) x
-#else
-#define vmx86_debug 0
-#define DEBUG_ONLY(x)
-#define vmx86_sl_debug 0
-#define SL_DEBUG_ONLY(x)
-#endif
-
-#ifdef VMX86_STATS
-#define vmx86_stats 1
-#define STATS_ONLY(x) x
-#else
-#define vmx86_stats 0
-#define STATS_ONLY(x)
-#endif
-
-#ifdef VMX86_DEVEL
-#define vmx86_devel 1
-#define DEVEL_ONLY(x) x
-#else
-#define vmx86_devel 0
-#define DEVEL_ONLY(x)
-#endif
-
-#ifdef VMX86_LOG
-#define vmx86_log 1
-#define LOG_ONLY(x) x
-#else
-#define vmx86_log 0
-#define LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_VMM_SERIAL_LOGGING
-#define vmx86_vmm_serial_log 1
-#define VMM_SERIAL_LOG_ONLY(x) x
-#else
-#define vmx86_vmm_serial_log 0
-#define VMM_SERIAL_LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_SERVER
-#define vmx86_server 1
-#define SERVER_ONLY(x) x
-#define HOSTED_ONLY(x)
-#else
-#define vmx86_server 0
-#define SERVER_ONLY(x)
-#define HOSTED_ONLY(x) x
-#endif
-
-#ifdef VMX86_WGS
-#define vmx86_wgs 1
-#define WGS_ONLY(x) x
-#else
-#define vmx86_wgs 0
-#define WGS_ONLY(x)
-#endif
-
-#ifdef VMKERNEL
-#define vmkernel 1
-#define VMKERNEL_ONLY(x) x
-#else
-#define vmkernel 0
-#define VMKERNEL_ONLY(x)
-#endif
-
-#ifdef _WIN32
-#define WIN32_ONLY(x) x
-#define POSIX_ONLY(x)
-#else
-#define WIN32_ONLY(x)
-#define POSIX_ONLY(x) x
-#endif
-
-#ifdef VMM
-#define VMM_ONLY(x) x
-#define USER_ONLY(x)
-#else
-#define VMM_ONLY(x)
-#define USER_ONLY(x) x
-#endif
-
-/* VMVISOR ifdef only allowed in the vmkernel */
-#ifdef VMKERNEL
-#ifdef VMVISOR
-#define vmvisor 1
-#define VMVISOR_ONLY(x) x
-#else
-#define vmvisor 0
-#define VMVISOR_ONLY(x)
-#endif
-#endif
-
-#ifdef _WIN32
-#define VMW_INVALID_HANDLE INVALID_HANDLE_VALUE
-#else
-#define VMW_INVALID_HANDLE (-1)
-#endif
-
-#ifdef _WIN32
-#define fsync(fd) _commit(fd)
-#define fileno(f) _fileno(f)
-#else
-#endif
-
-/*
- * Debug output macros for Windows drivers (the Eng variant is for
- * display/printer drivers only.
- */
-#ifdef _WIN32
-#ifndef USES_OLD_WINDDK
-#if defined(VMX86_DEBUG) || defined(ASSERT_ALWAYS_AVAILABLE)
-#define WinDrvPrint(arg, ...) DbgPrint(arg, __VA_ARGS__)
-#define WinDrvEngPrint(arg, ...) EngDbgPrint(arg, __VA_ARGS__)
-#else
-#define WinDrvPrint(arg, ...)
-#define WinDrvEngPrint(arg, ...)
-#endif
-#endif
-#endif // _WIN32
-
-#endif // ifndef _VM_BASIC_DEFS_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef VM_DEVICE_VERSION_H
-#define VM_DEVICE_VERSION_H
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMCORE
-#include "includeCheck.h"
-
-#ifdef _WIN32
-#include "guiddef.h"
-#endif
-
-/* LSILogic 53C1030 Parallel SCSI controller
- * LSILogic SAS1068 SAS controller
- */
-#define PCI_VENDOR_ID_LSILOGIC 0x1000
-#define PCI_DEVICE_ID_LSI53C1030 0x0030
-#define PCI_DEVICE_ID_LSISAS1068 0x0054
-
-/* Our own PCI IDs
- * VMware SVGA II (Unified VGA)
- * VMware SVGA (PCI Accelerator)
- * VMware vmxnet (Idealized NIC)
- * VMware vmxscsi (Abortive idealized SCSI controller)
- * VMware chipset (Subsystem ID for our motherboards)
- * VMware e1000 (Subsystem ID)
- * VMware vmxnet3 (Uniform Pass Through NIC)
- */
-#define PCI_VENDOR_ID_VMWARE 0x15AD
-#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
-#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
-#define PCI_DEVICE_ID_VMWARE_NET 0x0720
-#define PCI_DEVICE_ID_VMWARE_SCSI 0x0730
-#define PCI_DEVICE_ID_VMWARE_VMCI 0x0740
-#define PCI_DEVICE_ID_VMWARE_CHIPSET 0x1976
-#define PCI_DEVICE_ID_VMWARE_82545EM 0x0750 /* single port */
-#define PCI_DEVICE_ID_VMWARE_82546EB 0x0760 /* dual port */
-#define PCI_DEVICE_ID_VMWARE_EHCI 0x0770
-#define PCI_DEVICE_ID_VMWARE_1394 0x0780
-#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
-#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
-#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
-#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
-
-/* The hypervisor device might grow. Please leave room
- * for 7 more subfunctions.
- */
-#define PCI_DEVICE_ID_VMWARE_HYPER 0x0800
-#define PCI_DEVICE_ID_VMWARE_VMI 0x0801
-
-#define PCI_DEVICE_VMI_CLASS 0x05
-#define PCI_DEVICE_VMI_SUBCLASS 0x80
-#define PCI_DEVICE_VMI_INTERFACE 0x00
-#define PCI_DEVICE_VMI_REVISION 0x01
-
-/* From linux/pci_ids.h:
- * AMD Lance Ethernet controller
- * BusLogic SCSI controller
- * Ensoniq ES1371 sound controller
- */
-#define PCI_VENDOR_ID_AMD 0x1022
-#define PCI_DEVICE_ID_AMD_VLANCE 0x2000
-#define PCI_VENDOR_ID_BUSLOGIC 0x104B
-#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
-#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
-#define PCI_VENDOR_ID_ENSONIQ 0x1274
-#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
-
-/* From linux/pci_ids.h:
- * Intel 82439TX (430 HX North Bridge)
- * Intel 82371AB (PIIX4 South Bridge)
- * Intel 82443BX (440 BX North Bridge and AGP Bridge)
- * Intel 82545EM (e1000, server adapter, single port)
- * Intel 82546EB (e1000, server adapter, dual port)
- * Intel ICH7_16 (High Definition Audio controller)
- * Intel HECI (as embedded in ich9m)
- */
-#define PCI_VENDOR_ID_INTEL 0x8086
-#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
-#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
-#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
-#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
-#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
-#define PCI_DEVICE_ID_INTEL_82443BX 0x7190
-#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
-#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 /* Used when no AGP support */
-#define PCI_DEVICE_ID_INTEL_82545EM 0x100f
-#define PCI_DEVICE_ID_INTEL_82546EB 0x1010
-#define PCI_DEVICE_ID_INTEL_ICH7_16 0x27d8
-#define PCI_DEVICE_ID_INTEL_HECI 0x2a74
-
-
-/************* Strings for IDE Identity Fields **************************/
-#define VIDE_ID_SERIAL_STR "00000000000000000001" /* Must be 20 Bytes */
-#define VIDE_ID_FIRMWARE_STR "00000001" /* Must be 8 Bytes */
-
-/* No longer than 40 Bytes */
-#define VIDE_ATA_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE Hard Drive"
-#define VIDE_ATAPI_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE CDROM Drive"
-
-#define ATAPI_VENDOR_ID "NECVMWar" /* Must be 8 Bytes */
-#define ATAPI_PRODUCT_ID PRODUCT_GENERIC_NAME " IDE CDROM" /* Must be 16 Bytes */
-#define ATAPI_REV_LEVEL "1.00" /* Must be 4 Bytes */
-
-#define IDE_NUM_INTERFACES 2 /* support for two interfaces */
-#define IDE_DRIVES_PER_IF 2
-
-/************* Strings for SCSI Identity Fields **************************/
-#define SCSI_DISK_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI Hard Drive"
-#define SCSI_DISK_VENDOR_NAME COMPANY_NAME
-#define SCSI_DISK_REV_LEVEL "1.0"
-#define SCSI_CDROM_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI CDROM Drive"
-#define SCSI_CDROM_VENDOR_NAME COMPANY_NAME
-#define SCSI_CDROM_REV_LEVEL "1.0"
-
-/************* SCSI implementation limits ********************************/
-#define SCSI_MAX_CONTROLLERS 4 // Need more than 1 for MSCS clustering
-#define SCSI_MAX_DEVICES 16 // BT-958 emulates only 16
-#define SCSI_IDE_CHANNEL SCSI_MAX_CONTROLLERS
-#define SCSI_IDE_HOSTED_CHANNEL (SCSI_MAX_CONTROLLERS + 1)
-#define SCSI_MAX_CHANNELS (SCSI_MAX_CONTROLLERS + 2)
-
-/************* Strings for the VESA BIOS Identity Fields *****************/
-#define VBE_OEM_STRING COMPANY_NAME " SVGA"
-#define VBE_VENDOR_NAME COMPANY_NAME
-#define VBE_PRODUCT_NAME PRODUCT_GENERIC_NAME
-
-/************* PCI implementation limits ********************************/
-#define PCI_MAX_BRIDGES 15
-
-/************* Ethernet implementation limits ***************************/
-#define MAX_ETHERNET_CARDS 10
-
-/************* PCI Passthrough implementation limits ********************/
-#define MAX_PCI_PASSTHRU_DEVICES 2
-
-/************* USB implementation limits ********************************/
-#define MAX_USB_DEVICES_PER_HOST_CONTROLLER 127
-
-/************* Strings for Host USB Driver *******************************/
-
-#ifdef _WIN32
-
-/*
- * Globally unique ID for the VMware device interface. Define INITGUID before including
- * this header file to instantiate the variable.
- */
-DEFINE_GUID(GUID_DEVICE_INTERFACE_VMWARE_USB_DEVICES,
-0x2da1fe75, 0xaab3, 0x4d2c, 0xac, 0xdf, 0x39, 0x8, 0x8c, 0xad, 0xa6, 0x65);
-
-/*
- * Globally unique ID for the VMware device setup class.
- */
-DEFINE_GUID(GUID_CLASS_VMWARE_USB_DEVICES,
-0x3b3e62a5, 0x3556, 0x4d7e, 0xad, 0xad, 0xf5, 0xfa, 0x3a, 0x71, 0x2b, 0x56);
-
-/*
- * This string defines the device ID string of a VMware USB device.
- * The format is USB\Vid_XXXX&Pid_YYYY, where XXXX and YYYY are the
- * hexadecimal representations of the vendor and product ids, respectively.
- *
- * The official vendor ID for VMware, Inc. is 0x0E0F.
- * The product id for USB generic devices is 0x0001.
- */
-#define USB_VMWARE_DEVICE_ID_WIDE L"USB\\Vid_0E0F&Pid_0001"
-#define USB_DEVICE_ID_LENGTH (sizeof(USB_VMWARE_DEVICE_ID_WIDE) / sizeof(WCHAR))
-
-#ifdef UNICODE
-#define USB_PNP_SETUP_CLASS_NAME L"VMwareUSBDevices"
-#define USB_PNP_DRIVER_NAME L"vmusb"
-#else
-#define USB_PNP_SETUP_CLASS_NAME "VMwareUSBDevices"
-#define USB_PNP_DRIVER_NAME "vmusb"
-#endif
-#endif
-
-#endif /* VM_DEVICE_VERSION_H */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_end.h --
- *
- * End of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(pop)
-#elif __GNUC__
-__attribute__((__packed__))
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __VMWARE_PACK_INIT_H__
-# define __VMWARE_PACK_INIT_H__
-
-
-/*
- * vmware_pack_init.h --
- *
- * Platform-independent code to make the compiler pack (i.e. have them
- * occupy the smallest possible space) structure definitions. The following
- * constructs are known to work --hpreg
- *
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * ;
- *
- * typedef
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * foo;
- */
-
-
-#ifdef _MSC_VER
-/*
- * MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is
- * not balanced within 1 included file. That is annoying because our scheme
- * is based on the pairing being balanced between 2 included files.
- *
- * So we disable this warning, but this is safe because the compiler will also
- * emit warning 4161 when there is more pops than pushes within 1 main
- * file --hpreg
- */
-
-# pragma warning(disable:4103)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
-
-
-#endif /* __VMWARE_PACK_INIT_H__ */
/*
* Detect whether netif_rx_complete (and netif_rx_schedule) take a single
* napi_struct argument. The foundation was laid whith introducing Generic
- * Receive Offload infrastructure but sropping unneeded net_device argument
+ * Receive Offload infrastructure but dropping unneeded net_device argument
* did not happen till few commits later so we can't simply test for presence
* of NETIF_F_GRO.
+ *
+ * Test succeeds if netif_rx_complete takes dev & napi arguments, or if it
+ * takes dev argument only (kernels before 2.6.24). Test fails if netif_rx_complete
+ * takes only single napi argument.
*/
#include <linux/autoconf.h>
-#include <linux/netdevice.h>
+#include <linux/version.h>
-#ifndef NETIF_F_GRO
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
# error This compile test intentionally fails.
-#endif
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+#include <linux/netdevice.h>
-void test_netif_rx_complete(struct napi_struct *napi)
+#ifdef NETIF_F_GRO
+void test_netif_rx_complete(struct net_device *dev, struct napi_struct *napi)
{
- netif_rx_complete(napi);
+ netif_rx_complete(dev, napi);
}
+#endif
+
+#endif
/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
*
*********************************************************/
-/*
- * vmware_pack_begin.h --
- *
- * Begin of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
+#ifndef __COMPAT_MUTEX_H__
+# define __COMPAT_MUTEX_H__
+
+
+/* Blocking mutexes were introduced in 2.6.16. */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
-#include "vmware_pack_init.h"
+#include "compat_semaphore.h"
+typedef struct semaphore compat_mutex_t;
+
+# define compat_mutex_init(_mx) init_MUTEX(_mx)
+# define compat_mutex_lock(_mx) down(_mx)
+# define compat_mutex_unlock(_mx) up(_mx)
-#ifdef _MSC_VER
-# pragma pack(push, 1)
-#elif __GNUC__
#else
-# error Compiler packing...
+
+#include <linux/mutex.h>
+
+typedef struct mutex compat_mutex_t;
+
+# define compat_mutex_init(_mx) mutex_init(_mx)
+# define compat_mutex_lock(_mx) mutex_lock(_mx)
+# define compat_mutex_unlock(_mx) mutex_unlock(_mx)
+
#endif
+
+#endif /* __COMPAT_MUTEX_H__ */
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-#define compat_netif_napi_add(dev, napi, poll, quota) \
- netif_napi_add(dev, napi, poll, quota)
+# define compat_netif_napi_add(dev, napi, poll, quota) \
+ netif_napi_add(dev, napi, poll, quota)
-#ifdef VMW_NETIF_SINGLE_NAPI_PARM
-#define compat_netif_rx_complete(dev, napi) netif_rx_complete(napi)
-#define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(napi)
-#else
-#define compat_netif_rx_complete(dev, napi) netif_rx_complete(dev, napi)
-#define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(dev, napi)
-#endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) || \
+ defined VMW_NETIF_SINGLE_NAPI_PARM
+# define compat_napi_complete(dev, napi) napi_complete(napi)
+# define compat_napi_schedule(dev, napi) napi_schedule(napi)
+# else
+# define compat_napi_complete(dev, napi) netif_rx_complete(dev, napi)
+# define compat_napi_schedule(dev, napi) netif_rx_schedule(dev, napi)
+# endif
-#define compat_napi_enable(dev, napi) napi_enable(napi)
-#define compat_napi_disable(dev, napi) napi_disable(napi)
+# define compat_napi_enable(dev, napi) napi_enable(napi)
+# define compat_napi_disable(dev, napi) napi_disable(napi)
#else
struct napi_struct {
int dummy;
};
-#define compat_netif_napi_add(dev, napi, pollcb, quota) \
+# define compat_netif_napi_add(dev, napi, pollcb, quota) \
do { \
(dev)->poll = (pollcb); \
(dev)->weight = (quota);\
} while (0)
-#define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(dev)
-#define compat_napi_enable(dev, napi) netif_poll_enable(dev)
-#define compat_napi_disable(dev, napi) netif_poll_disable(dev)
+# define compat_napi_complete(dev, napi) netif_rx_complete(dev)
+# define compat_napi_schedule(dev, napi) netif_rx_schedule(dev)
+# define compat_napi_enable(dev, napi) netif_poll_enable(dev)
+# define compat_napi_disable(dev, napi) netif_poll_disable(dev)
#endif
#endif /* __COMPAT_NETDEVICE_H__ */
# define compat_sk_socket socket
# define compat_sk_ack_backlog ack_backlog
# define compat_sk_max_ack_backlog max_ack_backlog
+# define compat_sk_user_data user_data
#else
# define compat_sk_backlog_rcv sk_backlog_rcv
# define compat_sk_destruct sk_destruct
# define compat_sk_socket sk_socket
# define compat_sk_ack_backlog sk_ack_backlog
# define compat_sk_max_ack_backlog sk_max_ack_backlog
+# define compat_sk_user_data sk_user_data
#endif
# define compat_sk_del_node_init(sk, list) sk_del_node_init(sk)
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
+# define compat_sock_create_kern sock_create
+#else
+# define compat_sock_create_kern sock_create_kern
+#endif
+
#endif /* __COMPAT_SOCK_H__ */
#include "includeCheck.h"
#include "vmci_defs.h"
+#include "vm_assert.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMCIVA64ToPtr --
+ *
+ * Convert a VA64 to a pointer.
+ *
+ * Results:
+ * Virtual address.
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static INLINE void *
+VMCIVA64ToPtr(VA64 va64) // IN
+{
+#ifdef VM_X86_64
+ ASSERT_ON_COMPILE(sizeof (void *) == 8);
+#else
+ ASSERT_ON_COMPILE(sizeof (void *) == 4);
+ // Check that nothing of value will be lost.
+ ASSERT(!(va64 >> 32));
+#endif
+ return (void *)(uintptr_t)va64;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMCIPtrToVA64 --
+ *
+ * Convert a pointer to a VA64.
+ *
+ * Results:
+ * Virtual address.
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static INLINE VA64
+VMCIPtrToVA64(void const *ptr) // IN
+{
+ ASSERT_ON_COMPILE(sizeof ptr <= sizeof (VA64));
+ return (VA64)(uintptr_t)ptr;
+}
+
/*
* Driver version.
VMCI_SO_CTX_SET_CPT_STATE = IOCTL_VMCI_CTX_SET_CPT_STATE,
VMCI_SO_GET_CONTEXT_ID = IOCTL_VMCI_GET_CONTEXT_ID,
VMCI_SO_USERFD,
+ VMCI_SO_VMCID_RPC = IOCTL_VMCI_VMCID_RPC,
};
# define VMCI_MACOS_HOST_DEVICE_BASE "com.vmware.kext.vmci"
* vmci_kernel_if.h --
*
* This file defines helper functions for VMCI host _and_ guest
- * kernel code. It must work for windows, macosx, vmkernel and
- * linux kernel, ie. using defines where necessary.
- */
+ * kernel code. It must work for Windows, Mac OS, vmkernel, Linux and
+ * Solaris kernels, i.e. using defines where necessary.
+ */
#ifndef _VMCI_KERNEL_IF_H_
#define _VMCI_KERNEL_IF_H_
#include "vm_basic_types.h"
#include "vmci_defs.h"
+#if defined(__APPLE__)
+# include "dbllnklst.h"
+#endif
+
/* Flags for specifying memory type. */
#define VMCI_MEMORY_NORMAL 0x0
#define VMCI_MEMORY_ATOMIC 0x1
#elif defined(__APPLE__)
typedef IOLock *VMCILock;
typedef unsigned long VMCILockFlags;
- typedef semaphore_t VMCIEvent;
+ typedef struct {
+ IOLock *lock;
+ DblLnkLst_Links waiters;
+ int buffered;
+ } VMCIEvent;
typedef IOLock *VMCIMutex;
typedef void *VMCIPpnList; /* Actually a pointer to the C++ Object IOMemoryDescriptor */
#elif defined(_WIN32)
void VMCI_ReleaseBuffer(void *ptr);
void VMCI_FreeBuffer(VMCIBuffer buf, size_t size);
#ifdef SOLARIS
-int VMCI_CopyToUser(void *dst, const void *src, unsigned int len, int mode);
+int VMCI_CopyToUser(VA64 dst, const void *src, size_t len, int mode);
#else
-int VMCI_CopyToUser(void *dst, const void *src, unsigned int len);
+int VMCI_CopyToUser(VA64 dst, const void *src, size_t len);
/*
* Don't need the following for guests, hence no Solaris code for this
* function.
void VMCI_SignalEvent(VMCIEvent *event);
void VMCI_WaitOnEvent(VMCIEvent *event, VMCIEventReleaseCB releaseCB,
void *clientData);
-#if (defined(__linux__) || defined(_WIN32)) && !defined(VMKERNEL)
+#if (defined(__APPLE__) || defined(__linux__) || defined(_WIN32)) && !defined(VMKERNEL)
Bool VMCI_WaitOnEventInterruptible(VMCIEvent *event,
VMCIEventReleaseCB releaseCB,
void *clientData);
#if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \
defined(__APPLE__) || defined(SOLARIS))
-int VMCI_CopyFromUser(void *dst, const void *src, size_t len);
+int VMCI_CopyFromUser(void *dst, VA64 src, size_t len);
#endif
int VMCIMutex_Init(VMCIMutex *mutex);
#if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \
defined(SOLARIS) || defined(__APPLE__))
-VA VMCI_AllocQueueKVA(uint64 size);
-void VMCI_FreeQueueKVA(VA va, uint64 size);
+void *VMCI_AllocQueue(uint64 size);
+void VMCI_FreeQueue(void *q, uint64 size);
typedef struct PPNSet {
uint64 numProducePages;
uint64 numConsumePages;
VMCIPpnList consumePPNs;
Bool initialized;
} PPNSet;
-int VMCI_AllocPPNSet(VA produceVA, uint64 numProducePages, VA consumeVA,
+int VMCI_AllocPPNSet(void *produceQ, uint64 numProducePages, void *consumeQ,
uint64 numConsumePages, PPNSet *ppnSet);
void VMCI_FreePPNSet(PPNSet *ppnSet);
int VMCI_PopulatePPNList(uint8 *callBuf, const PPNSet *ppnSet);
#endif
-#if (defined(_WIN32) || defined(__linux__)) && !defined(VMKERNEL) && \
- !defined(VMX86_TOOLS)
+#if !defined(VMX86_TOOLS) && !defined(VMKERNEL)
struct PageStoreAttachInfo;
struct VMCIQueue;
void VMCIHost_DetachMappings(struct PageStoreAttachInfo *attach);
#endif
-#endif // _VMCI_KERNEL_IF_H_
+#endif // _VMCI_KERNEL_IF_H_
#include "vm_atomic.h"
#include "vmci_defs.h"
#include "vm_assert.h"
-#if defined(SOLARIS)
+#if defined(SOLARIS) || defined(__APPLE__)
#include <sys/uio.h>
#endif
#include "vmci_kernel_if.h"
#endif
+#if defined __APPLE__
+#include <string.h>
+#endif // __APPLE__
#if defined(__linux__) && defined(__KERNEL__)
struct page;
/*
* Wrappers below are being used to call Atomic_Read32 because of the
* 'type punned' compilation warning received when Atomic_Read32 is
- * called with a Atomic_uint64 pointer typecasted to Atomic_uint32
+ * called with a Atomic_uint64 pointer typecasted to Atomic_uint32
* pointer from QPAtomic_ReadOffset. Ditto with QPAtomic_WriteOffset.
*/
{
Atomic_Write32((Atomic_uint32 *)(var), (uint32)(val));
}
-
+
# define QP_MAX_QUEUE_SIZE_ARCH CONST64U(0xffffffff)
# define QPAtomic_ReadOffset(x) TypeSafe_Atomic_Read32((void *)(x))
# define QPAtomic_WriteOffset(x, y) \
* Solaris Kernel Guest.
*
* kmem_cache_alloc with object size of one page is being used to get
- * page aligned memory for queueHeader. VMCIQueue stores a pointer to
- * the queueHeader and the array of virtual addresses of actual pages
+ * page aligned memory for queueHeader. VMCIQueue stores a pointer to
+ * the queueHeader and the array of virtual addresses of actual pages
* that contain the queue data.
*/
typedef struct VMCIQueue {
# else
/*
- * VMX App and Windows Kernel Guest
+ * VMX App, Windows Kernel Guest, and Mac Kernel Guest
*
* The VMCIQueue is two or more machine pages where the first
* contains the queue header and the second and subsequent pages
VMCIQueueHeader *queueHeaderPtr;
struct page **page;
} VMCIQueue;
+# elif defined(__APPLE__)
+ /*
+ * Mac OS X Host
+ * The VMCIQueueHeader has been created elsewhere and this
+ * structure (VMCIQueue) needs a pointer to that
+ * VMCIQueueHeader.
+ *
+ * Also, the queue contents are managed dynamically by
+ * mapping/unmapping the pages. All we need is the VA64
+ * base address of the buffer to do that.
+ *
+ * Note, too, that the buffer contains one page of queue
+ * header information (head and tail pointers). But, that
+ * for the life of the VMCIQueue structure's life the
+ * buffer value contains the address past the header info.
+ * This modification happens during FinishAttach and is
+ * never reversed.
+ */
+ typedef struct VMCIQueue {
+ VMCIQueueHeader *queueHeaderPtr;
+ VA64 buffer;
+ } VMCIQueue;
# else
/*
* Windows Host
*
* VMCIMemcpy{To,From}Queue[v]() prototypes (and, in some cases, an
* inline version).
- *
+ *
*-----------------------------------------------------------------------------
*/
-#if defined (SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
+#if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
+ (defined(__linux__) && defined(__KERNEL__))
int VMCIMemcpyToQueue(VMCIQueue *queue, uint64 queueOffset, const void *src,
size_t srcOffset, size_t size);
int VMCIMemcpyFromQueue(void *dest, size_t destOffset, const VMCIQueue *queue,
*
* Results:
* VMCI_ERROR_QUEUEPAIR_NOSPACE if no space was available to enqueue data.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
+ * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
* (as defined by the queue size).
* Otherwise, the number of bytes written to the queue is returned.
*
*
* Results:
* VMCI_ERROR_QUEUEPAIR_NOSPACE if no space was available to enqueue data.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
+ * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
* (as defined by the queue size).
* Otherwise, the number of bytes written to the queue is returned.
*
}
-#if defined (SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
+#if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
+ (defined(__linux__) && defined(__KERNEL__))
/*
*-----------------------------------------------------------------------------
*
*
* Results:
* VMCI_ERROR_QUEUEPAIR_NOSPACE if no space was available to enqueue data.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
+ * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
* (as defined by the queue size).
* Otherwise, the number of bytes written to the queue is returned.
*
*
* Results:
* VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
+ * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
* (as defined by the queue size).
* Otherwise the number of bytes dequeued is returned.
*
}
-#if defined(SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
+#if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
+ (defined(__linux__) && defined(__KERNEL__))
/*
*-----------------------------------------------------------------------------
*
*
* Results:
* VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
+ * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
* (as defined by the queue size).
* Otherwise the number of bytes dequeued is returned.
*
*
* Results:
* VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
+ * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
* (as defined by the queue size).
* Otherwise the number of bytes copied to user buffer is returned.
*
}
-#if defined(SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
+#if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
+ (defined(__linux__) && defined(__KERNEL__))
/*
*-----------------------------------------------------------------------------
*
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmblock
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#
##########################################################
-INCLUDE := -I$(SRCROOT)/include
+INCLUDE += -I$(SRCROOT)/include
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/skas1.c, -DVMW_SKAS_MMAP, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/skas1.c, -DVMW_SKAS_MMAP, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, )
# Note: These tests are inverted.
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/getsb1.c, , -DVMW_GETSB_2618)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/statfs1.c, , -DVMW_STATFS_2618)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/filldir1.c, , -DVMW_FILLDIR_2618)
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/getsb1.c, , -DVMW_GETSB_2618)
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/statfs1.c, , -DVMW_STATFS_2618)
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/filldir1.c, , -DVMW_FILLDIR_2618)
obj-m += $(DRIVER).o
CC_OPTS := -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS)
-INCLUDE := -I$(SRCROOT)/include
+INCLUDE += -I$(SRCROOT)/include
INCLUDE += -I$(SRCROOT)/linux
INCLUDE += -I$(SRCROOT)/common
INCLUDE += -I$(HEADER_DIR)
-INCLUDE += $(shell $(CC) $(INCLUDE) -E $(SRCROOT)/autoconf/geninclude.c \
+INCLUDE += $(shell $(CC) $(INCLUDE) -E $(AUTOCONF_DIR)/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/skas1.c, -DVMW_SKAS_MMAP, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/skas1.c, -DVMW_SKAS_MMAP, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
CC_OPTS += -DVMW_KMEMCR_HAS_DTOR
LINUX_OBJS := module.o
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * All kernels before 2.6.22 take 6 arguments. All kernels since
- * 2.6.23-rc1 take 5 arguments. Only kernels between 2.6.22 and
- * 2.6.23-rc1 are questionable - we could ignore them if we wanted,
- * nobody cares about them even now. But unfortunately RedHat is
- * re-releasing 2.6.X-rc kernels under 2.6.(X-1) name, so they
- * are releasing 2.6.23-rc1 as 2.6.22-5055-something, so we have
- * to do autodetection for them.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
-/* Success... */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#error "This test intentionally fails on 2.6.23 and newer kernels."
-#else
-#include <linux/slab.h>
-
-struct kmem_cache *kmemtest(void) {
- return kmem_cache_create("test", 12, 0, 0, NULL, NULL);
-}
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * Between 2.6.23 and 2.6.24-rc1 ctor prototype was changed from
- * ctor(ptr, cache, flags) to ctor(cache, ptr). Unfortunately there
- * is no typedef for ctor, so we have to redefine kmem_cache_create
- * to find out ctor prototype. This assumes that kmem_cache_create
- * takes 5 arguments and not 6 - that change occured between
- * 2.6.22 and 2.6.23-rc1. If prototype matches, then this is old
- * kernel.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-#error "This test intentionally fails on 2.6.24 and newer kernels."
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#include <linux/slab.h>
-
-struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
- unsigned long,
- void (*)(void *, struct kmem_cache *, unsigned long));
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-
-#ifdef CONFIG_X86_VOYAGER
-APATH/mach-voyager
-#endif
-#ifdef CONFIG_X86_VISWS
-APATH/mach-visws
-#endif
-#ifdef CONFIG_X86_NUMAQ
-APATH/mach-numaq
-#endif
-#ifdef CONFIG_X86_BIGSMP
-APATH/mach-bigsmp
-#endif
-#ifdef CONFIG_X86_SUMMIT
-APATH/mach-summit
-#endif
-#ifdef CONFIG_X86_GENERICARCH
-APATH/mach-generic
-#endif
-APATH/mach-default
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_assert.h --
- *
- * The basic assertion facility for all VMware code.
- *
- * For proper use, see
- * http://vmweb.vmware.com/~mts/WebSite/guide/programming/asserts.html
- */
-
-#ifndef _VM_ASSERT_H_
-#define _VM_ASSERT_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-// XXX not necessary except some places include vm_assert.h improperly
-#include "vm_basic_types.h"
-#include "vm_basic_defs.h"
-
-
-/*
- * XXX old file code
- */
-
-#ifdef FILECODEINT
-#error "Don't define FILECODEINT. It is obsolete."
-#endif
-#ifdef FILECODE
-#error "Don't define FILECODE. It is obsolete."
-#endif
-
-
-/*
- * Panic and log functions
- */
-
-EXTERN void Log(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN void Warning(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2);
-
-EXTERN void LogThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-EXTERN void WarningThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-
-/* DB family: messages which are parsed by logfile database system */
-#define WarningDB Warning
-#define LogDB Log
-#define WarningThrottledDB WarningThrottled
-#define LogThrottledDB LogThrottled
-
-
-/*
- * Stress testing: redefine ASSERT_IFNOT() to taste
- */
-
-#ifndef ASSERT_IFNOT
- /*
- * PR 271512: When compiling with gcc, catch assignments inside an ASSERT.
- *
- * 'UNLIKELY' is defined with __builtin_expect, which does not warn when passed an
- * assignment (gcc bug 36050).
- * To get around this, we put 'cond' in an 'if' statement and make sure it never gets
- * executed by putting that inside of 'if (0)'.
- * We use gcc's statement expression syntax to make ASSERT an expression because some
- * code uses it that way.
- *
- * Since statement expression syntax is a gcc extension and since it's not clear if
- * this is a problem with other compilers, the ASSERT definition was not changed for
- * them. Using a bare 'cond' with the ternary operator may provide a solution.
- */
- #ifdef __GNUC__
- #define ASSERT_IFNOT(cond, panic) \
- ({if (UNLIKELY(!(cond))) { panic; if (0) { if (cond) { ; } } } (void)0;})
- #else
- #define ASSERT_IFNOT(cond, panic) \
- (UNLIKELY(!(cond)) ? (panic) : (void)0)
- #endif
-#endif
-
-
-/*
- * Assert, panic, and log macros
- *
- * Some of these are redefined below undef !VMX86_DEBUG.
- * ASSERT() is special cased because of interaction with Windows DDK.
- */
-
-#if defined VMX86_DEBUG || defined ASSERT_ALWAYS_AVAILABLE
-#undef ASSERT
-#define ASSERT(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertAssert))
-#endif
-#define ASSERT_BUG(bug, cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC_BUG(bug, AssertAssert))
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ASSERT_BUG(bug, cond)
-
-#define PANIC() _ASSERT_PANIC(AssertPanic)
-#define PANIC_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertPanic)
-
-#define ASSERT_NOT_IMPLEMENTED(cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED())
-#define ASSERT_NOT_IMPLEMENTED_BUG(bug, cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED_BUG(bug))
-
-#define NOT_IMPLEMENTED() _ASSERT_PANIC(AssertNotImplemented)
-#define NOT_IMPLEMENTED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotImplemented)
-
-#define NOT_REACHED() _ASSERT_PANIC(AssertNotReached)
-#define NOT_REACHED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotReached)
-
-#define ASSERT_MEM_ALLOC(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertMemAlloc))
-
-#ifdef VMX86_DEVEL
- #define ASSERT_LENGTH(real, expected) \
- ASSERT_IFNOT((real) == (expected), \
- Panic(AssertLengthFmt, __FILE__, __LINE__, real, expected))
-#else
- #define ASSERT_LENGTH(real, expected) ASSERT((real) == (expected))
-#endif
-
-#ifdef VMX86_DEVEL
- #define ASSERT_DEVEL(cond) ASSERT(cond)
-#else
- #define ASSERT_DEVEL(cond) ((void) 0)
-#endif
-
-#define ASSERT_NO_INTERRUPTS() ASSERT(!INTERRUPTS_ENABLED())
-#define ASSERT_HAS_INTERRUPTS() ASSERT(INTERRUPTS_ENABLED())
-
-#define ASSERT_LOG_UNEXPECTED(bug, cond) \
- (UNLIKELY(!(cond)) ? LOG_UNEXPECTED(bug) : 0)
-#ifdef VMX86_DEVEL
- #define LOG_UNEXPECTED(bug) \
- Warning(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#else
- #define LOG_UNEXPECTED(bug) \
- Log(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#endif
-
-#define ASSERT_NOT_TESTED(cond) (UNLIKELY(!(cond)) ? NOT_TESTED() : 0)
-#ifdef VMX86_DEVEL
- #define NOT_TESTED() Warning(AssertNotTestedFmt, __FILE__, __LINE__)
-#else
- #define NOT_TESTED() Log(AssertNotTestedFmt, __FILE__, __LINE__)
-#endif
-
-#define NOT_TESTED_ONCE() \
- do { \
- static Bool alreadyPrinted = FALSE; \
- if (UNLIKELY(!alreadyPrinted)) { \
- alreadyPrinted = TRUE; \
- NOT_TESTED(); \
- } \
- } while (0)
-
-#define NOT_TESTED_1024() \
- do { \
- static uint16 count = 0; \
- if (UNLIKELY(count == 0)) { NOT_TESTED(); } \
- count = (count + 1) & 1023; \
- } while (0)
-
-#define LOG_ONCE(_s) \
- do { \
- static Bool logged = FALSE; \
- if (!logged) { \
- Log _s; \
- logged = TRUE; \
- } \
- } while (0)
-
-
-/*
- * Redefine macros that are only in debug versions
- */
-
-#if !defined VMX86_DEBUG && !defined ASSERT_ALWAYS_AVAILABLE // {
-
-#undef ASSERT
-#define ASSERT(cond) ((void) 0)
-
-#undef ASSERT_BUG_DEBUGONLY
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ((void) 0)
-
-#undef ASSERT_LENGTH
-#define ASSERT_LENGTH(real, expected) ((void) 0)
-
-/*
- * Expand NOT_REACHED() as appropriate for each situation.
- *
- * Mainly, we want the compiler to infer the same control-flow
- * information as it would from Panic(). Otherwise, different
- * compilation options will lead to different control-flow-derived
- * errors, causing some make targets to fail while others succeed.
- *
- * VC++ has the __assume() built-in function which we don't trust
- * (see bug 43485); gcc has no such construct; we just panic in
- * userlevel code. The monitor doesn't want to pay the size penalty
- * (measured at 212 bytes for the release vmm for a minimal infinite
- * loop; panic would cost even more) so it does without and lives
- * with the inconsistency.
- */
-
-#ifdef VMM
-#undef NOT_REACHED
-#define NOT_REACHED() ((void) 0)
-#else
-// keep debug definition
-#endif
-
-#undef ASSERT_LOG_UNEXPECTED
-#define ASSERT_LOG_UNEXPECTED(bug, cond) ((void) 0)
-
-#undef LOG_UNEXPECTED
-#define LOG_UNEXPECTED(bug) ((void) 0)
-
-#undef ASSERT_NOT_TESTED
-#define ASSERT_NOT_TESTED(cond) ((void) 0)
-#undef NOT_TESTED
-#define NOT_TESTED() ((void) 0)
-#undef NOT_TESTED_ONCE
-#define NOT_TESTED_ONCE() ((void) 0)
-#undef NOT_TESTED_1024
-#define NOT_TESTED_1024() ((void) 0)
-
-#endif // !VMX86_DEBUG }
-
-
-/*
- * Compile-time assertions.
- *
- * ASSERT_ON_COMPILE does not use the common
- * switch (0) { case 0: case (e): ; } trick because some compilers (e.g. MSVC)
- * generate code for it.
- *
- * The implementation uses both enum and typedef because the typedef alone is
- * insufficient; gcc allows arrays to be declared with non-constant expressions
- * (even in typedefs, where it makes no sense).
- */
-
-#define ASSERT_ON_COMPILE(e) \
- do { \
- enum { AssertOnCompileMisused = ((e) ? 1 : -1) }; \
- typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \
- } while (0)
-
-
-/*
- * To put an ASSERT_ON_COMPILE() outside a function, wrap it
- * in MY_ASSERTS(). The first parameter must be unique in
- * each .c file where it appears. For example,
- *
- * MY_ASSERTS(FS3_INT,
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLock) == 128);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLockReserved) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskBlock) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(Hardware_DMIUUID) == 16);
- * )
- *
- * Caution: ASSERT() within MY_ASSERTS() is silently ignored.
- * The same goes for anything else not evaluated at compile time.
- */
-
-#define MY_ASSERTS(name, assertions) \
- static INLINE void name(void) { \
- assertions \
- }
-
-
-/*
- * Internal macros, functions, and strings
- *
- * The monitor wants to save space at call sites, so it has specialized
- * functions for each situation. User level wants to save on implementation
- * so it uses generic functions.
- */
-
-#if !defined VMM || defined MONITOR_APP // {
-
-#define _ASSERT_PANIC(name) \
- Panic(_##name##Fmt "\n", __FILE__, __LINE__)
-#define _ASSERT_PANIC_BUG(bug, name) \
- Panic(_##name##Fmt " bugNr=%d\n", __FILE__, __LINE__, bug)
-
-#define AssertLengthFmt _AssertLengthFmt
-#define AssertUnexpectedFmt _AssertUnexpectedFmt
-#define AssertNotTestedFmt _AssertNotTestedFmt
-
-#endif // }
-
-// these don't have newline so a bug can be tacked on
-#define _AssertPanicFmt "PANIC %s:%d"
-#define _AssertAssertFmt "ASSERT %s:%d"
-#define _AssertNotImplementedFmt "NOT_IMPLEMENTED %s:%d"
-#define _AssertNotReachedFmt "NOT_REACHED %s:%d"
-#define _AssertMemAllocFmt "MEM_ALLOC %s:%d"
-
-// these are complete formats with newline
-#define _AssertLengthFmt "LENGTH %s:%d r=%#x e=%#x\n"
-#define _AssertUnexpectedFmt "UNEXPECTED %s:%d bugNr=%d\n"
-#define _AssertNotTestedFmt "NOT_TESTED %s:%d\n"
-
-#endif /* ifndef _VM_ASSERT_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- *
- * vm_basic_types.h --
- *
- * basic data types.
- */
-
-
-#ifndef _VM_BASIC_TYPES_H_
-#define _VM_BASIC_TYPES_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-/* STRICT ANSI means the Xserver build and X defines Bool differently. */
-#if !defined(__STRICT_ANSI__) || defined(__FreeBSD__)
-typedef char Bool;
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define IsBool(x) (((x) & ~1) == 0)
-#define IsBool2(x, y) ((((x) | (y)) & ~1) == 0)
-
-/*
- * Macros __i386__ and __ia64 are intrinsically defined by GCC
- */
-#ifdef __i386__
-#define VM_I386
-#endif
-
-#ifdef _WIN64
-#define __x86_64__
-#endif
-
-#ifdef __x86_64__
-#define VM_X86_64
-#define VM_I386
-#define vm_x86_64 (1)
-#else
-#define vm_x86_64 (0)
-#endif
-
-
-
-#ifdef _WIN32
-/* safe assumption for a while */
-#define VM_I386
-#endif
-
-#ifdef _MSC_VER
-
-#pragma warning (3 :4505) // unreferenced local function
-#pragma warning (disable :4018) // signed/unsigned mismatch
-#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
-#pragma warning (disable :4305) // truncation from 'const int' to 'short'
-#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
-#pragma warning (disable :4267) // truncation of 'size_t'
-#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
-#pragma warning (disable :4142) // benign redefinition of type
-
-#endif
-
-#if defined(__APPLE__) || defined(HAVE_STDINT_H)
-
-/*
- * TODO: This is a C99 standard header. We should be able to test for
- * #if __STDC_VERSION__ >= 199901L, but that breaks the Netware build
- * (which doesn't have stdint.h).
- */
-
-#include <stdint.h>
-
-typedef uint64_t uint64;
-typedef int64_t int64;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint8_t uint8;
-
-/*
- * XXX: int8_t is defined to be 'signed char' on Mac hosts.
- *
- * Unfortunately, GCC 4.0.1 warns when doing pointer assignment or
- * comparison between signed char * and char * (even if char is
- * signed).
- *
- * If we want to use int8_t to define int8, we need to go through and
- * replace uses of char * with signed char * to prevent warnings.
- */
-typedef char int8;
-
-#else /* !HAVE_STDINT_H */
-
-#ifdef _MSC_VER
-
-typedef unsigned __int64 uint64;
-typedef signed __int64 int64;
-
-#elif __GNUC__
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-#if defined(VM_X86_64)
-typedef unsigned long uint64;
-typedef long int64;
-#else
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#elif __FreeBSD__
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#else
-#error - Need compiler define for int64/uint64
-#endif /* _MSC_VER */
-
-typedef unsigned int uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
-typedef int int32;
-typedef short int16;
-typedef char int8;
-
-#endif /* HAVE_STDINT_H */
-
-/*
- * FreeBSD (for the tools build) unconditionally defines these in
- * sys/inttypes.h so don't redefine them if this file has already
- * been included. [greg]
- *
- * This applies to Solaris as well.
- */
-
-/*
- * Before trying to do the includes based on OS defines, see if we can use
- * feature-based defines to get as much functionality as possible
- */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_INTTYPES_H
-#include <sys/inttypes.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
-#endif
-
-#if !defined(USING_AUTOCONF)
-# if defined(__FreeBSD__) || defined(sun)
-# ifdef KLD_MODULE
-# include <sys/types.h>
-# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
-# include <sys/types.h>
-# else
-# include <sys/inttypes.h>
-# endif
-# endif
-# elif defined __APPLE__
-# if KERNEL
-# include <sys/unistd.h>
-# include <sys/types.h> /* mostly for size_t */
-# include <stdint.h>
-# else
-# include <unistd.h>
-# include <inttypes.h>
-# include <stdlib.h>
-# include <stdint.h>
-# endif
-# else
-# if !defined(__intptr_t_defined) && !defined(intptr_t)
-# define __intptr_t_defined
-# define intptr_t intptr_t
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef int64 intptr_t;
-# else
-typedef int32 intptr_t;
-# endif
-# endif
-# endif
-
-# ifndef _STDINT_H
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef uint64 uintptr_t;
-# else
-typedef uint32 uintptr_t;
-# endif
-# endif
-# endif
-# endif
-#endif
-
-
-/*
- * Time
- * XXX These should be cleaned up. -- edward
- */
-
-typedef int64 VmTimeType; /* Time in microseconds */
-typedef int64 VmTimeRealClock; /* Real clock kept in microseconds */
-typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */
-
-/*
- * Printf format specifiers for size_t and 64-bit number.
- * Use them like this:
- * printf("%"FMT64"d\n", big);
- *
- * FMTH is for handles/fds.
- */
-
-#ifdef _MSC_VER
- #define FMT64 "I64"
- #ifdef VM_X86_64
- #define FMTSZ "I64"
- #define FMTPD "I64"
- #define FMTH "I64"
- #else
- #define FMTSZ "I"
- #define FMTPD "I"
- #define FMTH "I"
- #endif
-#elif defined __APPLE__
- /* Mac OS hosts use the same formatters for 32- and 64-bit. */
- #define FMT64 "ll"
- #define FMTSZ "z"
- #define FMTPD "l"
- #define FMTH ""
-#elif __GNUC__
- #define FMTH ""
- #if defined(N_PLAT_NLM) || defined(sun) || \
- (defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) < 5))
- /*
- * Why (__FreeBSD__ + 0)? See bug 141008.
- * Yes, we really need to test both (__FreeBSD__ + 0) and
- * ((__FreeBSD__ + 0) < 5). No, we can't remove "+ 0" from
- * ((__FreeBSD__ + 0) < 5).
- */
- #ifdef VM_X86_64
- #define FMTSZ "l"
- #define FMTPD "l"
- #else
- #define FMTSZ ""
- #define FMTPD ""
- #endif
- #elif defined(__linux__) \
- || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
- || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
- || (defined(_POSIX2_VERSION) && _POSIX2_VERSION >= 200112L)
- /* BSD, Linux */
- #define FMTSZ "z"
-
- #if defined(VM_X86_64)
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #else
- /* Systems with a pre-C99 libc */
- #define FMTSZ "Z"
- #ifdef VM_X86_64
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #endif
- #ifdef VM_X86_64
- #define FMT64 "l"
- #elif defined(sun) || defined(__FreeBSD__)
- #define FMT64 "ll"
- #else
- #define FMT64 "L"
- #endif
-#else
- #error - Need compiler define for FMT64 and FMTSZ
-#endif
-
-/*
- * Suffix for 64-bit constants. Use it like this:
- * CONST64(0x7fffffffffffffff) for signed or
- * CONST64U(0x7fffffffffffffff) for unsigned.
- *
- * 2004.08.30(thutt):
- * The vmcore/asm64/gen* programs are compiled as 32-bit
- * applications, but must handle 64 bit constants. If the
- * 64-bit-constant defining macros are already defined, the
- * definition will not be overwritten.
- */
-
-#if !defined(CONST64) || !defined(CONST64U)
-#ifdef _MSC_VER
-#define CONST64(c) c##I64
-#define CONST64U(c) c##uI64
-#elif defined __APPLE__
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#elif __GNUC__
-#ifdef VM_X86_64
-#define CONST64(c) c##L
-#define CONST64U(c) c##uL
-#else
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#endif
-#else
-#error - Need compiler define for CONST64
-#endif
-#endif
-
-/*
- * Use CONST3264/CONST3264U if you want a constant to be
- * treated as a 32-bit number on 32-bit compiles and
- * a 64-bit number on 64-bit compiles. Useful in the case
- * of shifts, like (CONST3264U(1) << x), where x could be
- * more than 31 on a 64-bit compile.
- */
-
-#ifdef VM_X86_64
- #define CONST3264(a) CONST64(a)
- #define CONST3264U(a) CONST64U(a)
-#else
- #define CONST3264(a) (a)
- #define CONST3264U(a) (a)
-#endif
-
-#define MIN_INT32 ((int32)0x80000000)
-#define MAX_INT32 ((int32)0x7fffffff)
-
-#define MIN_UINT32 ((uint32)0)
-#define MAX_UINT32 ((uint32)0xffffffff)
-
-#define MIN_INT64 (CONST64(0x8000000000000000))
-#define MAX_INT64 (CONST64(0x7fffffffffffffff))
-
-#define MIN_UINT64 (CONST64U(0))
-#define MAX_UINT64 (CONST64U(0xffffffffffffffff))
-
-typedef uint8 *TCA; /* Pointer into TC (usually). */
-
-/*
- * Type big enough to hold an integer between 0..100
- */
-typedef uint8 Percent;
-#define AsPercent(v) ((Percent)(v))
-#define CHOOSE_PERCENT AsPercent(101)
-
-
-typedef uintptr_t VA;
-typedef uintptr_t VPN;
-
-typedef uint64 PA;
-typedef uint32 PPN;
-
-typedef uint64 PhysMemOff;
-typedef uint64 PhysMemSize;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 BA;
-#endif
-typedef uint32 BPN;
-typedef uint32 PageNum;
-typedef unsigned MemHandle;
-typedef int32 World_ID;
-
-#define INVALID_WORLD_ID ((World_ID)-1)
-
-typedef World_ID User_CartelID;
-#define INVALID_CARTEL_ID INVALID_WORLD_ID
-
-typedef User_CartelID User_SessionID;
-#define INVALID_SESSION_ID INVALID_CARTEL_ID
-
-typedef User_CartelID User_CartelGroupID;
-#define INVALID_CARTELGROUP_ID INVALID_CARTEL_ID
-
-typedef uint32 Worldlet_ID;
-#define INVALID_WORLDLET_ID ((Worldlet_ID)-1)
-
-/* world page number */
-typedef uint32 WPN;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 MA;
-typedef uint32 MPN;
-#endif
-
-/*
- * This type should be used for variables that contain sector
- * position/quantity.
- */
-typedef uint64 SectorType;
-
-/*
- * Linear address
- */
-
-typedef uintptr_t LA;
-typedef uintptr_t LPN;
-#define LA_2_LPN(_la) ((_la) >> PAGE_SHIFT)
-#define LPN_2_LA(_lpn) ((_lpn) << PAGE_SHIFT)
-
-#define LAST_LPN ((((LA) 1) << (8 * sizeof(LA) - PAGE_SHIFT)) - 1)
-#define LAST_LPN32 ((((LA32)1) << (8 * sizeof(LA32) - PAGE_SHIFT)) - 1)
-#define LAST_LPN64 ((((LA64)1) << (8 * sizeof(LA64) - PAGE_SHIFT)) - 1)
-
-/* Valid bits in a LPN. */
-#define LPN_MASK LAST_LPN
-#define LPN_MASK32 LAST_LPN32
-#define LPN_MASK64 LAST_LPN64
-
-/*
- * On 64 bit platform, address and page number types default
- * to 64 bit. When we need to represent a 32 bit address, we use
- * types defined below.
- *
- * On 32 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint32 VA32;
-typedef uint32 VPN32;
-typedef uint32 LA32;
-typedef uint32 LPN32;
-typedef uint32 PA32;
-typedef uint32 PPN32;
-typedef uint32 MA32;
-typedef uint32 MPN32;
-
-/*
- * On 64 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint64 VA64;
-typedef uint64 VPN64;
-typedef uint64 LA64;
-typedef uint64 LPN64;
-typedef uint64 PA64;
-typedef uint64 PPN64;
-typedef uint64 MA64;
-typedef uint64 MPN64;
-
-/*
- * VA typedefs for user world apps.
- */
-typedef VA32 UserVA32;
-typedef VA64 UserVA64;
-typedef UserVA64 UserVAConst; /* Userspace ptr to data that we may only read. */
-typedef UserVA32 UserVA32Const; /* Userspace ptr to data that we may only read. */
-typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */
-#ifdef VMKERNEL
-typedef UserVA64 UserVA;
-#else
-typedef void * UserVA;
-#endif
-
-
-/*
- * Maximal possible PPN value (errors too) that PhysMem can handle.
- * Must be at least as large as MAX_PPN which is the maximum PPN
- * for any region other than buserror.
- */
-#define PHYSMEM_MAX_PPN ((PPN)0xffffffff)
-#define MAX_PPN ((PPN)0x1fffffff) /* Maximal observable PPN value. */
-#define INVALID_PPN ((PPN)0xffffffff)
-
-#define INVALID_BPN ((BPN) 0x1fffffff)
-
-#define INVALID_MPN ((MPN)-1)
-#define MEMREF_MPN ((MPN)-2)
-#define RESERVED_MPN ((MPN) 0)
-/* Support 43 bits of address space. */
-#define MAX_MPN ((MPN)0x7fffffff)
-
-#define INVALID_LPN ((LPN)-1)
-#define INVALID_VPN ((VPN)-1)
-#define INVALID_LPN64 ((LPN64)-1)
-#define INVALID_PAGENUM ((PageNum)-1)
-#define INVALID_WPN ((WPN) -1)
-
-
-/*
- * Format modifier for printing VA, LA, and VPN.
- * Use them like this: Log("%#"FMTLA"x\n", laddr)
- */
-
-#if defined(VMM64) || defined(FROBOS64) || vm_x86_64 || defined __APPLE__
-# define FMTLA "l"
-# define FMTVA "l"
-# define FMTVPN "l"
-#else
-# define FMTLA ""
-# define FMTVA ""
-# define FMTVPN ""
-#endif
-
-#ifndef EXTERN
-#define EXTERN extern
-#endif
-#define CONST const
-
-
-#ifndef INLINE
-# ifdef _MSC_VER
-# define INLINE __inline
-# else
-# define INLINE inline
-# endif
-#endif
-
-
-/*
- * Annotation for data that may be exported into a DLL and used by other
- * apps that load that DLL and import the data.
- */
-#if defined(_WIN32) && defined(VMX86_IMPORT_DLLDATA)
-# define VMX86_EXTERN_DATA extern __declspec(dllimport)
-#else // !_WIN32
-# define VMX86_EXTERN_DATA extern
-#endif
-
-#if defined(_WIN32) && !defined(VMX86_NO_THREADS)
-#define THREADSPECIFIC __declspec(thread)
-#else
-#define THREADSPECIFIC
-#endif
-
-/*
- * Due to the wonderful "registry redirection" feature introduced in
- * 64-bit Windows, if you access any key under HKLM\Software in 64-bit
- * code, you need to open/create/delete that key with
- * VMKEY_WOW64_32KEY if you want a consistent view with 32-bit code.
- */
-
-#ifdef _WIN32
-#ifdef _WIN64
-#define VMW_KEY_WOW64_32KEY KEY_WOW64_32KEY
-#else
-#define VMW_KEY_WOW64_32KEY 0x0
-#endif
-#endif
-
-
-/*
- * Consider the following reasons functions are inlined:
- *
- * 1) inlined for performance reasons
- * 2) inlined because it's a single-use function
- *
- * Functions which meet only condition 2 should be marked with this
- * inline macro; It is not critical to be inlined (but there is a
- * code-space & runtime savings by doing so), so when other callers
- * are added the inline-ness should be removed.
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-/*
- * Starting at version 3.3, gcc does not always inline functions marked
- * 'inline' (it depends on their size). To force gcc to do so, one must use the
- * extra __always_inline__ attribute.
- */
-# define INLINE_SINGLE_CALLER INLINE __attribute__((__always_inline__))
-# if defined(VMM) \
- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
-# warning Verify INLINE_SINGLE_CALLER '__always_inline__' attribute (did \
- monitor size change?)
-# endif
-#else
-# define INLINE_SINGLE_CALLER INLINE
-#endif
-
-/*
- * Used when a hard guaranteed of no inlining is needed. Very few
- * instances need this since the absence of INLINE is a good hint
- * that gcc will not do inlining.
- */
-
-#if defined(__GNUC__) && defined(VMM)
-#define ABSOLUTELY_NOINLINE __attribute__((__noinline__))
-#endif
-
-/*
- * Attributes placed on function declarations to tell the compiler
- * that the function never returns.
- */
-
-#ifdef _MSC_VER
-#define NORETURN __declspec(noreturn)
-#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9)
-#define NORETURN __attribute__((__noreturn__))
-#else
-#define NORETURN
-#endif
-
-/*
- * GCC 3.2 inline asm needs the + constraint for input/ouput memory operands.
- * Older GCCs don't know about it --hpreg
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
-# define VM_ASM_PLUS 1
-#else
-# define VM_ASM_PLUS 0
-#endif
-
-/*
- * Branch prediction hints:
- * LIKELY(exp) - Expression exp is likely TRUE.
- * UNLIKELY(exp) - Expression exp is likely FALSE.
- * Usage example:
- * if (LIKELY(excCode == EXC_NONE)) {
- * or
- * if (UNLIKELY(REAL_MODE(vc))) {
- *
- * We know how to predict branches on gcc3 and later (hopefully),
- * all others we don't so we do nothing.
- */
-
-#if (__GNUC__ >= 3)
-/*
- * gcc3 uses __builtin_expect() to inform the compiler of an expected value.
- * We use this to inform the static branch predictor. The '!!' in LIKELY
- * will convert any !=0 to a 1.
- */
-#define LIKELY(_exp) __builtin_expect(!!(_exp), 1)
-#define UNLIKELY(_exp) __builtin_expect((_exp), 0)
-#else
-#define LIKELY(_exp) (_exp)
-#define UNLIKELY(_exp) (_exp)
-#endif
-
-/*
- * GCC's argument checking for printf-like functions
- * This is conditional until we have replaced all `"%x", void *'
- * with `"0x%08x", (uint32) void *'. Note that %p prints different things
- * on different platforms. Argument checking is enabled for the
- * vmkernel, which has already been cleansed.
- *
- * fmtPos is the position of the format string argument, beginning at 1
- * varPos is the position of the variable argument, beginning at 1
- */
-
-#if defined(__GNUC__)
-# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
-#else
-# define PRINTF_DECL(fmtPos, varPos)
-#endif
-
-#if defined(__GNUC__)
-# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
-#else
-# define SCANF_DECL(fmtPos, varPos)
-#endif
-
-/*
- * UNUSED_PARAM should surround the parameter name and type declaration,
- * e.g. "int MyFunction(int var1, UNUSED_PARAM(int var2))"
- *
- */
-
-#ifndef UNUSED_PARAM
-# if defined(__GNUC__)
-# define UNUSED_PARAM(_parm) _parm __attribute__((__unused__))
-# else
-# define UNUSED_PARAM(_parm) _parm
-# endif
-#endif
-
-/*
- * REGPARM defaults to REGPARM3, i.e., a requent that gcc
- * puts the first three arguments in registers. (It is fine
- * if the function has fewer than three args.) Gcc only.
- * Syntactically, put REGPARM where you'd put INLINE or NORETURN.
- */
-
-#if defined(__GNUC__)
-# define REGPARM0 __attribute__((regparm(0)))
-# define REGPARM1 __attribute__((regparm(1)))
-# define REGPARM2 __attribute__((regparm(2)))
-# define REGPARM3 __attribute__((regparm(3)))
-# define REGPARM REGPARM3
-#else
-# define REGPARM0
-# define REGPARM1
-# define REGPARM2
-# define REGPARM3
-# define REGPARM
-#endif
-
-/*
- * ALIGNED specifies minimum alignment in "n" bytes.
- */
-
-#ifdef __GNUC__
-#define ALIGNED(n) __attribute__((__aligned__(n)))
-#else
-#define ALIGNED(n)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_OFFSET_CHECK -- */ /**
- *
- * \brief Check if the actual offsef of a member in a structure
- * is what is expected
- *
- *
- * \param[in] STRUCT Structure the member is a part of.
- * \param[in] MEMBER Member to check the offset of.
- * \param[in] OFFSET Expected offset of MEMBER in STRUCTURE.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to OFFSET to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == (OFFSET + DEBUG_EXTRA))
-#else
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == OFFSET)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_SIZE_CHECK -- */ /**
- *
- * \brief Check if the actual size of a structure is what is expected
- *
- *
- * \param[in] STRUCT Structure whose size is to be checked.
- * \param[in] SIZE Expected size of STRUCT.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to SIZE to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == (SIZE + DEBUG_EXTRA))
-#else
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == SIZE)
-#endif
-
-/*
- * __func__ is a stringified function name that is part of the C99 standard. The block
- * below defines __func__ on older systems where the compiler does not support that
- * macro.
- */
-#if defined(__GNUC__) \
- && ((__GNUC__ == 2 && __GNUC_MINOR < 96) \
- || (__GNUC__ < 2))
-# define __func__ __FUNCTION__
-#endif
-
-/*
- * Once upon a time, this was used to silence compiler warnings that
- * get generated when the compiler thinks that a function returns
- * when it is marked noreturn. Don't do it. Use NOT_REACHED().
- */
-
-#define INFINITE_LOOP() do { } while (1)
-
-/*
- * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_
- * is defined. Use the same logic here so we don't define it twice. [greg]
- */
-#ifdef __FreeBSD__
-# ifdef _BSD_SIZE_T_
-# undef _BSD_SIZE_T_
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# ifdef _BSD_SSIZE_T_
-# undef _BSD_SSIZE_T_
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#else
-# ifndef _SIZE_T
-# define _SIZE_T
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(ssize_t) && \
- !defined(__ssize_t_defined) && !defined(_SSIZE_T_DECLARED)
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#endif
-
-/*
- * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The pid is %"FMTPID".\n", pid);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTPID "d"
-# else
-# define FMTPID "lu"
-# endif
-#else
-# define FMTPID "d"
-#endif
-
-/*
- * Format modifier for printing uid_t. On Solaris 10 and earlier, uid_t
- * is a ulong, but on other platforms it's an unsigned int.
- * Use this like this: printf("The uid is %"FMTUID".\n", uid);
- */
-#if defined(sun) && !defined(SOL11)
-# ifdef VM_X86_64
-# define FMTUID "u"
-# else
-# define FMTUID "lu"
-# endif
-#else
-# define FMTUID "u"
-#endif
-
-/*
- * Format modifier for printing mode_t. On sun the mode_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The mode is %"FMTMODE".\n", mode);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTMODE "o"
-# else
-# define FMTMODE "lo"
-# endif
-#else
-# define FMTMODE "o"
-#endif
-
-/*
- * Format modifier for printing time_t. Most platforms define a time_t to be
- * a long int, but on FreeBSD (as of 5.0, it seems), the time_t is a signed
- * size quantity. Refer to the definition of FMTSZ to see why we need silly
- * preprocessor arithmetic.
- * Use this like this: printf("The mode is %"FMTTIME".\n", time);
- */
-#if defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) >= 5)
-# define FMTTIME FMTSZ"d"
-#else
-# define FMTTIME "ld"
-#endif
-
-/*
- * Define MXSemaHandle here so both vmmon and vmx see this definition.
- */
-
-#ifdef _WIN32
-typedef uintptr_t MXSemaHandle;
-#else
-typedef int MXSemaHandle;
-#endif
-
-/*
- * Define type for poll device handles.
- */
-
-#ifdef _WIN32
-typedef uintptr_t PollDevHandle;
-#else
-typedef int PollDevHandle;
-#endif
-
-/*
- * Define the utf16_t type.
- */
-
-#if defined(_WIN32) && defined(_NATIVE_WCHAR_T_DEFINED)
-typedef wchar_t utf16_t;
-#else
-typedef uint16 utf16_t;
-#endif
-
-#endif /* _VM_BASIC_TYPES_H_ */
{
struct DblLnkLst_Links *curr;
- /* XXX The following is only temporary. */
-#ifdef __FreeBSD__
+ /*
+ * On FreeBSD we have a mechanism to assert (but not simply check)
+ * that a lock is held. Since semantic is different (panic that
+ * happens if assertion fails can not be suppressed) we are using
+ * different name.
+ */
+#ifdef os_assert_rwlock_held
os_assert_rwlock_held(&blockedFilesLock);
#else
ASSERT(os_rwlock_held(&blockedFilesLock));
/* Private initialization/cleanup routines */
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockSetProcEntryOwner --
+ *
+ * Sets proc_dir_entry owner if necessary:
+ *
+ * Before version 2.6.24 kernel prints nasty warning when in-use
+ * directory entry is destroyed, which happens when module is unloaded.
+ * We try to prevent this warning in most cases by setting owner to point
+ * to our module, so long operations (like current directory pointing to
+ * directory we created) prevent module from unloading. Since 2.6.24 this
+ * situation is handled without nastygrams, allowing module unload even
+ * when current directory points to directory created by unloaded module,
+ * so we do not have to set owner anymore. And since 2.6.29 we must not
+ * set owner at all, as there is none...
+ *
+ * Results:
+ * None. Always succeeds.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+VMBlockSetProcEntryOwner(struct proc_dir_entry *entry) // IN/OUT: directory entry
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
+ entry->owner = THIS_MODULE;
+#endif
+}
+
+
/*
*----------------------------------------------------------------------------
*
return -EINVAL;
}
- controlProcDirEntry->owner = THIS_MODULE;
+ VMBlockSetProcEntryOwner(controlProcDirEntry);
/* Create /proc/fs/vmblock/mountPoint */
controlProcMountpoint = proc_mkdir(VMBLOCK_CONTROL_MOUNTPOINT,
return -EINVAL;
}
- controlProcMountpoint->owner = THIS_MODULE;
+ VMBlockSetProcEntryOwner(controlProcMountpoint);
/* Create /proc/fs/vmblock/dev */
controlProcEntry = create_proc_entry(VMBLOCK_CONTROL_DEVNAME,
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmci
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#### VMware vmci Makefile to be distributed externally
####
-INCLUDE := -I.
+INCLUDE += -I.
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
EXTRA_CFLAGS += -DVMX86_TOOLS
obj-m += $(DRIVER).o
CC_OPTS := -g3 -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS)
-INCLUDE := -I. -I$(HEADER_DIR)
+INCLUDE += -I. -I$(HEADER_DIR)
INCLUDE += $(shell $(CC) $(CC_OPTS) $(INCLUDE) \
- -E $(SRCROOT)/autoconf/geninclude.c \
+ -E $(AUTOCONF_DIR)/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
OBJS := vmci_drv.o
OBJS += vmciDatagram.o
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Detect whether we have 'struct poll_wqueues'
- * 2.6.x kernels always had this struct. Stock 2.4.x kernels
- * never had it, but some distros backported epoll patch.
- */
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-#include <linux/poll.h>
-
-void poll_test(void) {
- struct poll_wqueues test;
-
- return poll_initwait(&test);
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-
-#ifdef CONFIG_X86_VOYAGER
-APATH/mach-voyager
-#endif
-#ifdef CONFIG_X86_VISWS
-APATH/mach-visws
-#endif
-#ifdef CONFIG_X86_NUMAQ
-APATH/mach-numaq
-#endif
-#ifdef CONFIG_X86_BIGSMP
-APATH/mach-bigsmp
-#endif
-#ifdef CONFIG_X86_SUMMIT
-APATH/mach-summit
-#endif
-#ifdef CONFIG_X86_GENERICARCH
-APATH/mach-generic
-#endif
-APATH/mach-default
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * circList.h --
- *
- * macros, prototypes and struct definitions for double-linked
- * circular lists.
- */
-
-#ifndef _CIRCLIST_H_
-#define _CIRCLIST_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#include "includeCheck.h"
-#include "vmware.h"
-
-typedef struct ListItem {
- struct ListItem *prev;
- struct ListItem *next;
-} ListItem;
-
-/* A list with no elements is a null pointer. */
-#define LIST_ITEM_DEF(name) \
- ListItem * name = NULL
-
-#define LIST_EMPTY(l) ((l) == NULL)
-
-/* initialize list item */
-#define INIT_LIST_ITEM(p) \
- do { \
- (p)->prev = (p)->next = (p); \
- } while (0)
-
-/* check if initialized */
-#define IS_LIST_ITEM_INITIALIZED(li) \
- (((li) == (li)->prev) && ((li) == (li)->next))
-
-/* return first element in the list */
-#define LIST_FIRST(l) (l)
-#define LIST_FIRST_CHK(l) (l)
-
-/* return last element in the list */
-#define LIST_LAST(l) ((l)->prev)
-#define LIST_LAST_CHK(l) (LIST_EMPTY(l) ? NULL : LIST_LAST(l))
-
-/*
- * LIST_CONTAINER - get the struct for this entry (like list_entry)
- * @ptr: the &struct ListItem pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list struct within the struct.
- */
-#define LIST_CONTAINER(ptr, type, member) \
- ((type *)((char *)(ptr) - offsetof(type, member)))
-
-/*
- * delete item from the list
- */
-#define LIST_DEL DelListItem
-
-/*
- * link two lists together
- */
-#define LIST_SPLICE SpliceLists
-
-/*
- * Split a list into two lists
- */
-#define LIST_SPLIT SplitLists
-
-/*
- * Add item to front of stack. List pointer points to new head.
- */
-#define LIST_PUSH PushListItem
-
-/*
- * Add item at back of queue. List pointer only changes if list was empty.
- */
-#define LIST_QUEUE QueueListItem
-
-/*
- * Get the list size.
- */
-#define LIST_SIZE GetListSize
-
-/*
- * LIST_SCAN_FROM scans the list from "from" up until "until".
- * The loop variable p should not be destroyed in the process.
- * "from" is an element in the list where to start scanning.
- * "until" is the element where search should stop.
- * member is the field to use for the search - either "next" or "prev".
- */
-#define LIST_SCAN_FROM(p, from, until, member) \
- for (p = (from); (p) != NULL; \
- (p) = (((p)->member == (until)) ? NULL : (p)->member))
-
-/* scan the entire list (non-destructively) */
-#define LIST_SCAN(p, l) \
- LIST_SCAN_FROM(p, LIST_FIRST(l), LIST_FIRST(l), next)
-
-
-/* scan a list backward from last element to first (non-destructively) */
-#define LIST_SCAN_BACK(p, l) \
- LIST_SCAN_FROM(p, LIST_LAST_CHK(l), LIST_LAST(l), prev)
-
-/* scan the entire list where loop element may be destroyed */
-#define LIST_SCAN_SAFE(p, pn, l) \
- if (!LIST_EMPTY(l)) \
- for (p = (l), (pn) = NextListItem(p, l); (p) != NULL; \
- (p) = (pn), (pn) = NextListItem(p, l))
-
-/* scan the entire list backwards where loop element may be destroyed */
-#define LIST_SCAN_BACK_SAFE(p, pn, l) \
- if (!LIST_EMPTY(l)) \
- for (p = LIST_LAST(l), (pn) = PrevListItem(p, l); (p) != NULL; \
- (p) = (pn), (pn) = PrevListItem(p, l))
-
-
-/* function definitions */
-
-/*
- *----------------------------------------------------------------------
- *
- * NextListItem --
- *
- * Returns the next member of a doubly linked list, or NULL if last.
- * Assumes: p is member of the list headed by head.
- *
- * Result
- * If head or p is NULL, return NULL. Otherwise,
- * next list member (or null if last).
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE ListItem *
-NextListItem(ListItem *p, // IN
- ListItem *head) // IN
-{
- if (head == NULL || p == NULL) {
- return NULL;
- }
- /* both p and head are non-null */
- p = p->next;
- return p == head ? NULL : p;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * PrevListItem --
- *
- * Returns the prev member of a doubly linked list, or NULL if first.
- * Assumes: p is member of the list headed by head.
- *
- * Result
- * If head or prev is NULL, return NULL. Otherwise,
- * prev list member (or null if first).
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE ListItem *
-PrevListItem(ListItem *p, // IN
- ListItem *head) // IN
-{
- if (head == NULL || p == NULL) {
- return NULL;
- }
- /* both p and head are non-null */
- return p == head ? NULL : p->prev;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * DelListItem --
- *
- * Deletes a member of a doubly linked list, possibly modifies the
- * list header itself.
- * Assumes neither p nor headp is null and p is a member of *headp.
- *
- * Result
- * None
- *
- * Side effects:
- * Modifies *headp.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE void
-DelListItem(ListItem *p, // IN
- ListItem **headp) // IN/OUT
-{
- ListItem *next;
-
- ASSERT(p);
- ASSERT(headp);
-
- next = p->next;
- if (p == next) {
- *headp = NULL;
- } else {
- next->prev = p->prev;
- p->prev->next = next;
- if (*headp == p) {
- *headp = next;
- }
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * QueueListItem --
- *
- * Adds a new member to the back of a doubly linked list (queue)
- * Assumes neither p nor headp is null and p is not a member of *headp.
- *
- * Result
- * None
- *
- * Side effects:
- * Modifies *headp.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE void
-QueueListItem(ListItem *p, // IN
- ListItem **headp) // IN/OUT
-{
- ListItem *head;
-
- head = *headp;
- if (LIST_EMPTY(head)) {
- INIT_LIST_ITEM(p);
- *headp = p;
- } else {
- p->prev = head->prev;
- p->next = head;
- p->prev->next = p;
- head->prev = p;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * PushListItem --
- *
- * Adds a new member to the front of a doubly linked list (stack)
- * Assumes neither p nor headp is null and p is not a member of *headp.
- *
- * Result
- * None
- *
- * Side effects:
- * Modifies *headp.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE void
-PushListItem(ListItem *p, // IN
- ListItem **headp) // IN/OUT
-{
- QueueListItem(p, headp);
- *headp = p;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * SpliceLists --
- *
- * Make a single list {l1 l2} from {l1} and {l2} and return it.
- * It is okay for one or both lists to be NULL.
- * No checking is done. It is assumed that l1 and l2 are two
- * distinct lists.
- *
- * Result
- * A list { l1 l2 }.
- *
- * Side effects:
- * Modifies l1 and l2 list pointers.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE ListItem *
-SpliceLists(ListItem *l1, // IN
- ListItem *l2) // IN
-{
- ListItem *l1Last, *l2Last;
-
- if (LIST_EMPTY(l1)) {
- return l2;
- }
-
- if (LIST_EMPTY(l2)) {
- return l1;
- }
-
- l1Last = l1->prev; /* last elem of l1 */
- l2Last = l2->prev; /* last elem of l2 */
-
- /*
- * l1 -> ... -> l1Last l2 -> ... l2Last
- */
- l1Last->next = l2;
- l2->prev = l1Last;
-
- l1->prev = l2Last;
- l2Last->next = l1;
-
- return l1;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * SplitLists --
- *
- * Make a list l = {l1 l2} into two separate lists {l1} and {l2}, where:
- * l = { ... x -> p -> ... } split into:
- * l1 = { ... -> x }
- * l2 = { p -> ... }
- * Assumes neither p nor l is null and p is a member of l.
- * If p is the first element of l, then l1 will be NULL.
- *
- * Result
- * None.
- *
- * Side effects:
- * Sets *l1p and *l2p to the resulting two lists.
- * Modifies l's pointers.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE void
-SplitLists(ListItem *p, // IN
- ListItem *l, // IN
- ListItem **l1p, // OUT
- ListItem **l2p) // OUT
-{
- ListItem *last;
-
- if (p == LIST_FIRST(l)) { /* first element */
- *l1p = NULL;
- *l2p = l;
- return;
- }
-
- last = l->prev;
-
- *l1p = l;
- p->prev->next = l;
- l->prev = p->prev;
-
- *l2p = p;
- p->prev = last;
- last->next = p;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GetListSize --
- *
- * Return the number of items in the list.
- *
- * Result:
- * The number of items in the list.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE int
-GetListSize(ListItem *head) // IN
-{
- ListItem *li;
- int ret = 0;
-
- LIST_SCAN(li, head) {
- ret++;
- }
- return ret;
-}
-
-#endif /* _CIRCLIST_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_COMPLETION_H__
-# define __COMPAT_COMPLETION_H__
-
-/*
- * The kernel's completion objects were made available for module use in 2.4.9.
- *
- * Between 2.4.0 and 2.4.9, we implement completions on our own using
- * waitqueues and counters. This was done so that we could safely support
- * functions like complete_all(), which cannot be implemented using semaphores.
- *
- * Prior to that, the waitqueue API is substantially different, and since none
- * of our modules that are built against older kernels need complete_all(),
- * we fallback on a simple semaphore-based implementation.
- */
-
-/*
- * Native completions.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#include <linux/completion.h>
-#define compat_completion struct completion
-#define compat_init_completion(comp) init_completion(comp)
-#define COMPAT_DECLARE_COMPLETION DECLARE_COMPLETION
-#define compat_wait_for_completion(comp) wait_for_completion(comp)
-#define compat_complete(comp) complete(comp)
-
-/* complete_all() was exported in 2.6.6. */
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
-# include "compat_wait.h"
-# include "compat_list.h"
-# include "compat_spinlock.h"
-# include "compat_sched.h"
-# define compat_complete_all(x) \
- ({ \
- struct list_head *currLinks; \
- spin_lock(&(x)->wait.lock); \
- (x)->done += UINT_MAX/2; \
- \
- list_for_each(currLinks, &(x)->wait.task_list) { \
- wait_queue_t *currQueue = list_entry(currLinks, wait_queue_t, task_list); \
- wake_up_process(currQueue->task); \
- } \
- spin_unlock(&(x)->wait.lock); \
- })
-# else
-# define compat_complete_all complete_all
-# endif
-
-/*
- * Completions via waitqueues.
- */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-
-/*
- * Kernel completions in 2.4.9 and beyond use a counter and a waitqueue, and
- * our implementation is quite similar. Because __wake_up_common() is not
- * exported, our implementations of compat_complete() and compat_complete_all()
- * are somewhat racy: the counter is incremented outside of the waitqueue's
- * lock.
- *
- * As a result, our completion cannot guarantee in-order wake ups. For example,
- * suppose thread A is entering compat_complete(), thread B is sleeping inside
- * compat_wait_for_completion(), and thread C is just now entering
- * compat_wait_for_completion(). If Thread A is scheduled first and increments
- * the counter, then gets swapped out, thread C may get scheduled and will
- * quickly go through compat_wait_for_completion() (since done != 0) while
- * thread B continues to sleep, even though thread B should have been the one
- * to wake up.
- */
-
-#include <asm/current.h>
-#include "compat_sched.h"
-#include "compat_list.h"
-#include <linux/smp_lock.h> // for lock_kernel()/unlock_kernel()
-#include "compat_wait.h"
-
-typedef struct compat_completion {
- unsigned int done;
- wait_queue_head_t wq;
-} compat_completion;
-
-#define compat_init_completion(comp) do { \
- (comp)->done = 0; \
- init_waitqueue_head(&(comp)->wq); \
-} while (0)
-#define COMPAT_DECLARE_COMPLETION(comp) \
- compat_completion comp = { \
- .done = 0, \
- .wq = __WAIT_QUEUE_HEAD_INITIALIZER((comp).wq), \
- }
-
-/*
- * Locking and unlocking the kernel lock here ensures that the thread
- * is no longer running in module code: compat_complete_and_exit
- * performs the sequence { lock_kernel(); up(comp); compat_exit(); }, with
- * the final unlock_kernel performed implicitly by the resident kernel
- * in do_exit.
- */
-#define compat_wait_for_completion(comp) do { \
- spin_lock_irq(&(comp)->wq.lock); \
- if (!(comp)->done) { \
- DECLARE_WAITQUEUE(wait, current); \
- wait.flags |= WQ_FLAG_EXCLUSIVE; \
- __add_wait_queue_tail(&(comp)->wq, &wait); \
- do { \
- __set_current_state(TASK_UNINTERRUPTIBLE); \
- spin_unlock_irq(&(comp)->wq.lock); \
- schedule(); \
- spin_lock_irq(&(comp)->wq.lock); \
- } while (!(comp)->done); \
- __remove_wait_queue(&(comp)->wq, &wait); \
- } \
- (comp)->done--; \
- spin_unlock_irq(&(comp)->wq.lock); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-/* XXX: I don't think I need to touch the BKL. */
-#define compat_complete(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done++; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up(&(comp)->wq); \
-} while (0)
-
-#define compat_complete_all(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done += UINT_MAX / 2; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up_all(&(comp)->wq); \
-} while (0)
-
-/*
- * Completions via semaphores.
- */
-#else
-
-#include "compat_semaphore.h"
-#define compat_completion struct semaphore
-#define compat_init_completion(comp) init_MUTEX_LOCKED(comp)
-#define COMPAT_DECLARE_COMPLETION(comp) DECLARE_MUTEX_LOCKED(comp)
-
-#define compat_wait_for_completion(comp) do { \
- down(comp); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-#define compat_complete(comp) up(comp)
-
-#endif
-
-#endif /* __COMPAT_COMPLETION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_FILE_H__
-# define __COMPAT_FILE_H__
-
-
-/* The fput() API is modified in 2.2.0 --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define compat_fput(_file) fput(_file)
-#else
-# define compat_fput(_file) fput(_file, (_file)->f_inode)
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-# define compat_get_file(_file) get_file(_file)
-# define compat_file_count(_file) file_count(_file)
-#else
-# define compat_get_file(_file) (_file)->f_count++
-# define compat_file_count(_file) (_file)->f_count
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 4)
-# define compat_filp_close(_file, _files) filp_close(_file, _files)
-#else
-static inline void compat_filp_close(struct file* filp, fl_owner_t files) {
- if (filp->f_op && filp->f_op->flush) {
- filp->f_op->flush(filp);
- }
- /*
- * Hopefully there are no locks to release on this filp.
- * locks_remove_posix is not exported so we cannot use it...
- */
- fput(filp);
-}
-#endif
-
-
-#endif /* __COMPAT_FILE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_init.h: Initialization compatibility wrappers.
- */
-
-#ifndef __COMPAT_INIT_H__
-#define __COMPAT_INIT_H__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-#include <linux/init.h>
-#endif
-
-#ifndef module_init
-#define module_init(x) int init_module(void) { return x(); }
-#endif
-
-#ifndef module_exit
-#define module_exit(x) void cleanup_module(void) { x(); }
-#endif
-
-#endif /* __COMPAT_INIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_INTERRUPT_H__
-# define __COMPAT_INTERRUPT_H__
-
-
-#include <linux/interrupt.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69)
-/*
- * We cannot just define irqreturn_t, as some 2.4.x kernels have
- * typedef void irqreturn_t; for "increasing" backward compatibility.
- */
-typedef void compat_irqreturn_t;
-#define COMPAT_IRQ_NONE
-#define COMPAT_IRQ_HANDLED
-#define COMPAT_IRQ_RETVAL(x)
-#else
-typedef irqreturn_t compat_irqreturn_t;
-#define COMPAT_IRQ_NONE IRQ_NONE
-#define COMPAT_IRQ_HANDLED IRQ_HANDLED
-#define COMPAT_IRQ_RETVAL(x) IRQ_RETVAL(x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
-#define COMPAT_IRQF_DISABLED SA_INTERRUPT
-#define COMPAT_IRQF_SHARED SA_SHIRQ
-#else
-#define COMPAT_IRQF_DISABLED IRQF_DISABLED
-#define COMPAT_IRQF_SHARED IRQF_SHARED
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
-#define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp, struct pt_regs *regs)
-#else
-#define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp)
-#endif
-
-#endif /* __COMPAT_INTERRUPT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_IOPORT_H__
-# define __COMPAT_IOPORT_H__
-
-
-#include <linux/ioport.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-static inline void *
-compat_request_region(unsigned long start, unsigned long len, const char *name)
-{
- if (check_region(start, len)) {
- return NULL;
- }
- request_region(start, len, name);
- return (void*)1;
-}
-#else
-#define compat_request_region(start, len, name) request_region(start, len, name)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 7)
-/* mmap io support starts from 2.3.7, fail the call for kernel prior to that */
-static inline void *
-compat_request_mem_region(unsigned long start, unsigned long len, const char *name)
-{
- return NULL;
-}
-
-static inline void
-compat_release_mem_region(unsigned long start, unsigned long len)
-{
- return;
-}
-#else
-#define compat_request_mem_region(start, len, name) request_mem_region(start, len, name)
-#define compat_release_mem_region(start, len) release_mem_region(start, len)
-#endif
-
-/* these two macro defs are needed by compat_pci_request_region */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15)
-# define IORESOURCE_IO 0x00000100
-# define IORESOURCE_MEM 0x00000200
-#endif
-
-#endif /* __COMPAT_IOPORT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_KERNEL_H__
-# define __COMPAT_KERNEL_H__
-
-#include <asm/unistd.h>
-#include <linux/kernel.h>
-
-/*
- * container_of was introduced in 2.5.28 but it's easier to check like this.
- */
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-/*
- * wait_for_completion and friends did not exist before 2.4.9.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#define compat_complete_and_exit(comp, status) complete_and_exit(comp, status)
-
-#else
-
-#include "compat_completion.h"
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-#define __NR_compat_exit __NR_exit
-static inline _syscall1(int, compat_exit, int, exit_code);
-
-/*
- * See compat_wait_for_completion in compat_completion.h.
- * compat_exit implicitly performs an unlock_kernel, in resident code,
- * ensuring that the thread is no longer running in module code when the
- * module is unloaded.
- */
-#define compat_complete_and_exit(comp, status) do { \
- lock_kernel(); \
- compat_complete(comp); \
- compat_exit(status); \
-} while (0)
-
-#endif
-
-/*
- * vsnprintf became available in 2.4.10. For older kernels, just fall back on
- * vsprintf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define vsnprintf(str, size, fmt, args) vsprintf(str, fmt, args)
-#endif
-
-#endif /* __COMPAT_KERNEL_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_LIST_H__
-# define __COMPAT_LIST_H__
-
-#include <linux/list.h>
-
-/*
- * list_add_tail is with us since 2.4.0, or something like that.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define list_add_tail(newe, head) do { \
- struct list_head *__h = (head); \
- __list_add((newe), __h->prev, __h); \
-} while (0)
-#endif
-
-/*
- * list_for_each_safe() showed up in 2.4.10, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_safe
-# define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-#endif
-
-/*
- * list_for_each_entry() showed up in 2.4.20, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_entry
-# define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-#endif
-
-#endif /* __COMPAT_LIST_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_MM_H__
-# define __COMPAT_MM_H__
-
-
-#include <linux/mm.h>
-
-
-/* The get_page() API appeared in 2.3.7 --hpreg */
-/* Sometime during development it became function instead of macro --petr */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(get_page)
-# define get_page(_page) atomic_inc(&(_page)->count)
-/* The __free_page() API is exported in 2.1.67 --hpreg */
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 67)
-# define put_page __free_page
-# else
-# include "compat_page.h"
-
-# define page_to_phys(_page) (page_to_pfn(_page) << PAGE_SHIFT)
-# define put_page(_page) free_page(page_to_phys(_page))
-# endif
-#endif
-
-
-/* page_count() is 2.4.0 invention. Unfortunately unavailable in some RedHat
- * kernels (for example 2.4.21-4-RHEL3). */
-/* It is function since 2.6.0, and hopefully RedHat will not play silly games
- * with mm_inline.h again... */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(page_count)
-# define page_count(page) atomic_read(&(page)->count)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-# define compat_vm_pgoff(vma) ((vma)->vm_offset >> PAGE_SHIFT)
-
-static inline unsigned long compat_do_mmap_pgoff(struct file *file, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long pgoff)
-{
- unsigned long ret = -EINVAL;
-
- if (pgoff < 1 << (32 - PAGE_SHIFT)) {
- ret = do_mmap(file, addr, len, prot, flag, pgoff << PAGE_SHIFT);
- }
- return ret;
-}
-
-#else
-# define compat_vm_pgoff(vma) (vma)->vm_pgoff
-# ifdef VMW_SKAS_MMAP
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(current->mm, f, a, l, p, g, o)
-# else
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(f, a, l, p, g, o)
-# endif
-#endif
-
-
-/* 2.2.x uses 0 instead of some define */
-#ifndef NOPAGE_SIGBUS
-#define NOPAGE_SIGBUS (0)
-#endif
-
-
-/* 2.2.x does not have HIGHMEM support */
-#ifndef GFP_HIGHUSER
-#define GFP_HIGHUSER (GFP_USER)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-
-#include "compat_page.h"
-
-static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
-{
- unsigned long addr;
-
- addr = __get_free_pages(gfp_mask, order);
- if (!addr) {
- return NULL;
- }
- return virt_to_page(addr);
-}
-#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
-
-#endif
-
-/*
- * In 2.4.14, the logic behind the UnlockPage macro was moved to the
- * unlock_page() function. Later (in 2.5.12), the UnlockPage macro was removed
- * altogether, and nowadays everyone uses unlock_page().
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 14)
-#define compat_unlock_page(page) UnlockPage(page)
-#else
-#define compat_unlock_page(page) unlock_page(page)
-#endif
-
-/*
- * In 2.4.10, vmtruncate was changed from returning void to returning int.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define compat_vmtruncate(inode, size) \
-({ \
- int result = 0; \
- vmtruncate(inode, size); \
- result; \
-})
-#else
-#define compat_vmtruncate(inode, size) vmtruncate(inode, size)
-#endif
-
-
-#endif /* __COMPAT_MM_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_PAGE_H__
-# define __COMPAT_PAGE_H__
-
-
-#include <linux/mm.h>
-#include <asm/page.h>
-
-
-/* The pfn_to_page() API appeared in 2.5.14 and changed to function during 2.6.x */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pfn_to_page)
-# define pfn_to_page(_pfn) (mem_map + (_pfn))
-# define page_to_pfn(_page) ((_page) - mem_map)
-#endif
-
-
-/* The virt_to_page() API appeared in 2.4.0 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(virt_to_page)
-# define virt_to_page(_kvAddr) pfn_to_page(MAP_NR(_kvAddr))
-#endif
-
-
-/*
- * The get_order() API appeared at some point in 2.3.x, and was then backported
- * in 2.2.17-21mdk and in the stock 2.2.18. Because we can only detect its
- * definition through makefile tricks, we provide our own for now --hpreg
- */
-static inline int
-compat_get_order(unsigned long size) // IN
-{
- int order;
-
- size = (size - 1) >> (PAGE_SHIFT - 1);
- order = -1;
- do {
- size >>= 1;
- order++;
- } while (size);
-
- return order;
-}
-
-/*
- * BUG() was added to <asm/page.h> in 2.2.18, and was moved to <asm/bug.h>
- * in 2.5.58.
- *
- * XXX: Technically, this belongs in some sort of "compat_asm_page.h" file, but
- * since our compatibility wrappers don't distinguish between <asm/xxx.h> and
- * <linux/xxx.h>, putting it here is reasonable.
- */
-#ifndef BUG
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- __asm__ __volatile__(".byte 0x0f,0x0b"); \
-} while (0)
-#endif
-
-#endif /* __COMPAT_PAGE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_pci.h: PCI compatibility wrappers.
- */
-
-#ifndef __COMPAT_PCI_H__
-#define __COMPAT_PCI_H__
-
-#include "compat_ioport.h"
-#include <linux/pci.h>
-#ifndef KERNEL_2_1
-# include <linux/bios32.h>
-#endif
-
-
-/* 2.0.x has useless struct pci_dev; remap it to our own */
-#ifndef KERNEL_2_1
-#define pci_dev vmw_pci_driver_instance
-#endif
-
-
-/* 2.0/2.2 does not have pci driver API */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-struct vmw_pci_driver_instance {
- struct vmw_pci_driver_instance *next;
- void *driver_data;
- struct pci_driver *pcidrv;
-#ifdef KERNEL_2_1
- struct pci_dev *pcidev;
-#else
- unsigned char bus;
- unsigned char devfn;
- unsigned int irq;
-#endif
-};
-#endif
-
-
-/* 2.0 has pcibios_* calls only... We have to provide pci_* compatible wrappers. */
-#ifndef KERNEL_2_1
-static inline int
-pci_read_config_byte(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Byte to read
- u8 *value) // OUT: Value read
-{
- return pcibios_read_config_byte(pdev->bus, pdev->devfn, where, value);
-}
-
-static inline int
-pci_read_config_dword(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Dword to read
- u32 *value) // OUT: Value read
-{
- return pcibios_read_config_dword(pdev->bus, pdev->devfn, where, value);
-}
-
-static inline int
-pci_write_config_dword(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Dword to write
- u32 value) // IN: Value to write
-{
- return pcibios_write_config_dword(pdev->bus, pdev->devfn, where, value);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * compat_pci_name --
- *
- * Return human readable PCI slot name. Note that some implementations
- * return a pointer to the static storage, so returned value may be
- * overwritten by subsequent calls to this function.
- *
- * Results:
- * Returns pointer to the string with slot name.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-#define compat_pci_name(pdev) pci_name(pdev)
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-#define compat_pci_name(pdev) (pdev)->slot_name
-#elif defined(KERNEL_2_1)
-static inline const char*
-compat_pci_name(struct pci_dev* pdev)
-{
- static char slot_name[12];
- sprintf(slot_name, "%02X:%02X.%X", pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
- return slot_name;
-}
-#else
-static inline const char*
-compat_pci_name(struct pci_dev* pdev)
-{
- static char slot_name[12];
- sprintf(slot_name, "%02X:%02X.%X", pdev->bus,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
- return slot_name;
-}
-#endif
-
-
-/* pci_resource_start comes in 4 flavors - 2.0, 2.2, early 2.3, 2.4+ */
-#ifndef KERNEL_2_1
-static inline unsigned long
-compat_pci_resource_start(struct pci_dev *pdev,
- unsigned int index)
-{
- u32 addr;
-
- if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
- printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
- index, compat_pci_name(pdev));
- return ~0UL;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return addr & PCI_BASE_ADDRESS_IO_MASK;
- } else {
- return addr & PCI_BASE_ADDRESS_MEM_MASK;
- }
-}
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
-# define compat_pci_resource_start(dev, index) \
- (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
- ? ((dev)->base_address[index] & PCI_BASE_ADDRESS_IO_MASK) \
- : ((dev)->base_address[index] & PCI_BASE_ADDRESS_MEM_MASK))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)
-# define compat_pci_resource_start(dev, index) \
- ((dev)->resource[index].start)
-#else
-# define compat_pci_resource_start(dev, index) \
- pci_resource_start(dev, index)
-#endif
-
-/* since 2.3.15, a new set of s/w res flags IORESOURCE_ is introduced,
- * we fake them by returning either IORESOURCE_{IO, MEM} prior to 2.3.15 since
- * this is what compat_pci_request_region uses
- */
-#ifndef KERNEL_2_1
-static inline unsigned long
-compat_pci_resource_flags(struct pci_dev *pdev,
- unsigned int index)
-{
- u32 addr;
-
- if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
- printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
- index, compat_pci_name(pdev));
- return ~0UL;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return IORESOURCE_IO;
- } else {
- return IORESOURCE_MEM;
- }
-}
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
-# define compat_pci_resource_flags(dev, index) \
- (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
- ? IORESOURCE_IO: IORESOURCE_MEM)
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15)
- /* IORESOURCE_xxx appeared in 2.3.15 and is set in resource[].flags */
-# define compat_pci_resource_flags(dev, index) ((dev)->resource[index].flags)
-#else
-# define compat_pci_resource_flags(dev, index) pci_resource_flags(dev, index)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
-static inline unsigned long
-compat_pci_resource_len(struct pci_dev *pdev, // IN
- unsigned int index) // IN
-{
- u32 addr, mask;
- unsigned char reg = PCI_BASE_ADDRESS_0 + index * 4;
-
- if (pci_read_config_dword(pdev, reg, &addr) || addr == 0xFFFFFFFF) {
- return 0;
- }
-
- pci_write_config_dword(pdev, reg, 0xFFFFFFFF);
- pci_read_config_dword(pdev, reg, &mask);
- pci_write_config_dword(pdev, reg, addr);
-
- if (mask == 0 || mask == 0xFFFFFFFF) {
- return 0;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return 65536 - (mask & PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
- } else {
- return -(mask & PCI_BASE_ADDRESS_MEM_MASK);
- }
-}
-#else
-#define compat_pci_resource_len(dev, index) pci_resource_len(dev, index)
-#endif
-
-/* pci_request_region appears in 2.4.20 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
-static inline int
-compat_pci_request_region(struct pci_dev *pdev, int bar, char *name)
-{
- if (compat_pci_resource_len(pdev, bar) == 0) {
- return 0;
- }
-
- if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
- if (!compat_request_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar),
- name)) {
- return -EBUSY;
- }
- } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
- if (!compat_request_mem_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar),
- name)) {
- return -EBUSY;
- }
- }
-
- return 0;
-}
-
-static inline void
-compat_pci_release_region(struct pci_dev *pdev, int bar)
-{
- if (compat_pci_resource_len(pdev, bar) != 0) {
- if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
- release_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar));
- } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
- compat_release_mem_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar));
- }
- }
-}
-#else
-#define compat_pci_request_region(pdev, bar, name) pci_request_region(pdev, bar, name)
-#define compat_pci_release_region(pdev, bar) pci_release_region(pdev, bar)
-#endif
-
-/* pci_request_regions appeears in 2.4.3 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)
-static inline int
-compat_pci_request_regions(struct pci_dev *pdev, char *name)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- if (compat_pci_request_region(pdev, i, name)) {
- goto release;
- }
- }
- return 0;
-
-release:
- while (--i >= 0) {
- compat_pci_release_region(pdev, i);
- }
- return -EBUSY;
-}
-static inline void
-compat_pci_release_regions(struct pci_dev *pdev)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- compat_pci_release_region(pdev, i);
- }
-}
-#else
-#define compat_pci_request_regions(pdev, name) pci_request_regions(pdev, name)
-#define compat_pci_release_regions(pdev) pci_release_regions(pdev)
-#endif
-
-/* pci_enable_device is available since 2.4.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define compat_pci_enable_device(pdev) (0)
-#else
-#define compat_pci_enable_device(pdev) pci_enable_device(pdev)
-#endif
-
-
-/* pci_set_master is available since 2.2.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-#define compat_pci_set_master(pdev) (0)
-#else
-#define compat_pci_set_master(pdev) pci_set_master(pdev)
-#endif
-
-
-/* pci_disable_device is available since 2.4.4 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 4)
-#define compat_pci_disable_device(pdev) do {} while (0)
-#else
-#define compat_pci_disable_device(pdev) pci_disable_device(pdev)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-/*
- * Devices supported by particular pci driver. While 2.4+ kernels
- * can do match on subsystem and class too, we support match on
- * vendor/device IDs only.
- */
-struct pci_device_id {
- unsigned int vendor, device;
- unsigned long driver_data;
-};
-#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev)
-
-/* PCI driver */
-struct pci_driver {
- const char *name;
- const struct pci_device_id *id_table;
- int (*probe)(struct pci_dev* dev, const struct pci_device_id* id);
- void (*remove)(struct pci_dev* dev);
-};
-
-
-/*
- * Note that this is static variable. Maybe everything below should be in
- * separate compat_pci.c file, but currently only user of this file is vmxnet,
- * and vmxnet has only one file, so it is fine. Also with vmxnet all
- * functions below are called just once, so difference between 'inline' and
- * separate compat_pci.c should be very small.
- */
-
-static struct vmw_pci_driver_instance *pci_driver_instances = NULL;
-
-#ifdef KERNEL_2_1
-#define vmw_pci_device(instance) (instance)->pcidev
-#else
-#define vmw_pci_device(instance) (instance)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_register_driver --
- *
- * Create driver instances for all matching PCI devices in the box.
- *
- * Results:
- * Returns 0 for success, negative error value for failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static inline int
-pci_register_driver(struct pci_driver *drv)
-{
- const struct pci_device_id *chipID;
-
- for (chipID = drv->id_table; chipID->vendor; chipID++) {
-#ifdef KERNEL_2_1
- struct pci_dev *pdev;
-
- for (pdev = NULL;
- (pdev = pci_find_device(chipID->vendor, chipID->device, pdev)) != NULL; ) {
-#else
- int adapter;
- unsigned char bus, devfn, irq;
-
- for (adapter = 0;
- pcibios_find_device(chipID->vendor, chipID->device, adapter,
- &bus, &devfn) == 0;
- adapter++) {
-#endif
- struct vmw_pci_driver_instance *pdi;
- int err;
-
- pdi = kmalloc(sizeof *pdi, GFP_KERNEL);
- if (!pdi) {
- printk(KERN_ERR "Not enough memory.\n");
- break;
- }
- pdi->pcidrv = drv;
-#ifdef KERNEL_2_1
- pdi->pcidev = pdev;
-#else
- pdi->bus = bus;
- pdi->devfn = devfn;
- if (pci_read_config_byte(pdi, PCI_INTERRUPT_LINE, &irq)) {
- pdi->irq = -1;
- } else {
- pdi->irq = irq;
- }
-#endif
- pdi->driver_data = NULL;
- pdi->next = pci_driver_instances;
- pci_driver_instances = pdi;
- err = drv->probe(vmw_pci_device(pdi), chipID);
- if (err) {
- pci_driver_instances = pdi->next;
- kfree(pdi);
- }
- }
- }
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * compat_pci_unregister_driver --
- *
- * Shut down PCI driver - unbind all device instances from driver.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static inline void
-pci_unregister_driver(struct pci_driver *drv)
-{
- struct vmw_pci_driver_instance **ppdi;
-
- ppdi = &pci_driver_instances;
- while (1) {
- struct vmw_pci_driver_instance *pdi = *ppdi;
-
- if (!pdi) {
- break;
- }
- if (pdi->pcidrv == drv) {
- drv->remove(vmw_pci_device(pdi));
- *ppdi = pdi->next;
- kfree(pdi);
- } else {
- ppdi = &pdi->next;
- }
- }
-}
-#else
-/* provide PCI_DEVICE for early 2.4.x kernels */
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif
-#endif
-
-
-/* provide dummy MODULE_DEVICE_TABLE for 2.0/2.2 */
-#ifndef MODULE_DEVICE_TABLE
-#define MODULE_DEVICE_TABLE(bus, devices)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_set_drvdata --
- *
- * Set per-device driver's private data.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_get_drvdata --
- *
- * Retrieve per-device driver's private data.
- *
- * Results:
- * per-device driver's data previously set by pci_set_drvdata,
- * or NULL on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-#ifndef KERNEL_2_1
-/* 2.0.x is simple, we have driver_data directly in pci_dev */
-#define pci_set_drvdata(pdev, data) do { (pdev)->driver_data = (data); } while (0)
-#define pci_get_drvdata(pdev) (pdev)->driver_data
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-/* 2.2.x is trickier, we have to find driver instance first */
-static inline void
-pci_set_drvdata(struct pci_dev *pdev, void* data)
-{
- struct vmw_pci_driver_instance *pdi;
-
- for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
- if (pdi->pcidev == pdev) {
- pdi->driver_data = data;
- return;
- }
- }
- printk(KERN_ERR "pci_set_drvdata issued for unknown device %p\n", pdev);
-}
-
-static inline void *
-pci_get_drvdata(struct pci_dev *pdev)
-{
- struct vmw_pci_driver_instance *pdi;
-
- for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
- if (pdi->pcidev == pdev) {
- return pdi->driver_data;
- }
- }
- printk(KERN_ERR "pci_get_drvdata issued for unknown device %p\n", pdev);
- return NULL;
-}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)
-# define PCI_DMA_BIDIRECTIONAL 0
-# define PCI_DMA_TODEVICE 1
-# define PCI_DMA_FROMDEVICE 2
-# define PCI_DMA_NONE 3
-#endif
-
-/*
- * Power Management related compat wrappers.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
-# define compat_pci_save_state(pdev) pci_save_state((pdev), NULL)
-# define compat_pci_restore_state(pdev) pci_restore_state((pdev), NULL)
-#else
-# define compat_pci_save_state(pdev) pci_save_state((pdev))
-# define compat_pci_restore_state(pdev) pci_restore_state((pdev))
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
-# define pm_message_t u32
-# define compat_pci_choose_state(pdev, state) (state)
-# define PCI_D0 0
-# define PCI_D3hot 3
-#else
-# define compat_pci_choose_state(pdev, state) pci_choose_state((pdev), (state))
-#endif
-
-/* 2.6.14 changed the PCI shutdown callback */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
-# define COMPAT_PCI_SHUTDOWN(func) .driver = { .shutdown = (func), }
-# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct device *(var))
-# define COMPAT_PCI_TO_DEV(dev) (to_pci_dev(dev))
-#else
-# define COMPAT_PCI_SHUTDOWN(func) .shutdown = (func)
-# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct pci_dev *(var))
-# define COMPAT_PCI_TO_DEV(dev) (dev)
-#endif
-
-
-#endif /* __COMPAT_PCI_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SCHED_H__
-# define __COMPAT_SCHED_H__
-
-
-#include <linux/sched.h>
-
-/* CLONE_KERNEL available in 2.5.35 and higher. */
-#ifndef CLONE_KERNEL
-#define CLONE_KERNEL CLONE_FILES | CLONE_FS | CLONE_SIGHAND
-#endif
-
-/* TASK_COMM_LEN become available in 2.6.11. */
-#ifndef TASK_COMM_LEN
-#define TASK_COMM_LEN 16
-#endif
-
-/* The capable() API appeared in 2.1.92 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 92)
-# define capable(_capability) suser()
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-# define need_resched() need_resched
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define need_resched() (current->need_resched)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define cond_resched() (need_resched() ? schedule() : (void) 0)
-#endif
-
-/* Oh well. We need yield... Happy us! */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
-# ifdef __x86_64__
-# define compat_yield() there_is_nothing_like_yield()
-# else
-# include <linux/unistd.h>
-# include <linux/kernel.h>
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-# define __NR_compat_yield __NR_sched_yield
-static inline _syscall0(int, compat_yield);
-# endif
-#else
-# define compat_yield() yield()
-#endif
-
-
-/*
- * Since 2.5.34 there are two methods to enumerate tasks:
- * for_each_process(p) { ... } which enumerates only tasks and
- * do_each_thread(g,t) { ... } while_each_thread(g,t) which enumerates
- * also threads even if they share same pid.
- */
-#ifndef for_each_process
-# define for_each_process(p) for_each_task(p)
-#endif
-
-#ifndef do_each_thread
-# define do_each_thread(g, t) for_each_task(g) { t = g; do
-# define while_each_thread(g, t) while (0) }
-#endif
-
-
-/*
- * Lock for signal mask is moving target...
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 40) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_sigmask_lock sigmask_lock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 60) && !defined(INIT_SIGHAND)
-/* RedHat's 2.4.x with first version of NPTL support, or 2.5.40 to 2.5.59 */
-#define compat_sigmask_lock sig->siglock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-/* RedHat's 2.4.x with second version of NPTL support, or 2.5.60+. */
-#define compat_sigmask_lock sighand->siglock
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(current, ¤t->blocked, (siginfo_ptr))
-#endif
-#endif
-
-/*
- * recalc_sigpending() had task argument in the past
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 29) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_recalc_sigpending() recalc_sigpending(current)
-#else
-/* RedHat's 2.4.x with NPTL support, or 2.5.29+ */
-#define compat_recalc_sigpending() recalc_sigpending()
-#endif
-
-
-/*
- * reparent_to_init() was introduced in 2.4.8. In 2.5.38 (or possibly
- * earlier, but later than 2.5.31) a call to it was added into
- * daemonize(), so compat_daemonize no longer needs to call it.
- *
- * In 2.4.x kernels reparent_to_init() forgets to do correct refcounting
- * on current->user. It is better to count one too many than one too few...
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 38)
-#define compat_reparent_to_init() do { \
- reparent_to_init(); \
- atomic_inc(¤t->user->__count); \
- } while (0)
-#else
-#define compat_reparent_to_init() do {} while (0)
-#endif
-
-
-/*
- * daemonize appeared in 2.2.18. Except 2.2.17-4-RH7.0, which has it too.
- * Fortunately 2.2.17-4-RH7.0 uses versioned symbols, so we can check
- * its existence with defined().
- */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) && !defined(daemonize)
-static inline void daemonize(void) {
- struct fs_struct *fs;
-
- exit_mm(current);
- current->session = 1;
- current->pgrp = 1;
- exit_fs(current);
- fs = init_task.fs;
- current->fs = fs;
- atomic_inc(&fs->count);
-}
-#endif
-
-
-/*
- * flush_signals acquires sighand->siglock since 2.5.61... Verify RH's kernels!
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_flush_signals(task) do { \
- spin_lock_irq(&task->compat_sigmask_lock); \
- flush_signals(task); \
- spin_unlock_irq(&task->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_flush_signals(task) flush_signals(task)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_allow_signal(signr) do { \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigdelset(¤t->blocked, signr); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_allow_signal(signr) allow_signal(signr)
-#endif
-
-/*
- * daemonize can set process name since 2.5.61. Prior to 2.5.61, daemonize
- * didn't block signals on our behalf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_daemonize(x...) \
-({ \
- /* Beware! No snprintf here, so verify arguments! */ \
- sprintf(current->comm, x); \
- \
- /* Block all signals. */ \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigfillset(¤t->blocked); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- compat_flush_signals(current); \
- \
- daemonize(); \
- compat_reparent_to_init(); \
-})
-#else
-#define compat_daemonize(x...) daemonize(x)
-#endif
-
-
-/*
- * set priority for specified thread. Exists on 2.6.x kernels and some
- * 2.4.x vendor's kernels.
- */
-#if defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) set_user_nice((task), (n))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define compat_set_user_nice(task, n) do { (task)->priority = 20 - (n); } while (0)
-#elif !defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) do { (task)->nice = (n); } while (0)
-#endif
-
-/*
- * try to freeze a process. For kernels 2.6.11 or newer, we know how to choose
- * the interface. The problem is that the oldest interface, introduced in
- * 2.5.18, was backported to 2.4.x kernels. So if we're older than 2.6.11,
- * we'll decide what to do based on whether or not swsusp was configured
- * for the kernel. For kernels 2.6.20 and newer, we'll also need to include
- * freezer.h since the try_to_freeze definition was pulled out of sched.h.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-#include <linux/freezer.h>
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) || defined(VMW_TL10S64_WORKAROUND)
-#define compat_try_to_freeze() try_to_freeze()
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
-#define compat_try_to_freeze() try_to_freeze(PF_FREEZE)
-#elif defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_SOFTWARE_SUSPEND2)
-#include "compat_mm.h"
-#include <linux/errno.h>
-#include <linux/suspend.h>
-static inline int compat_try_to_freeze(void) {
- if (current->flags & PF_FREEZE) {
- refrigerator(PF_FREEZE);
- return 1;
- } else {
- return 0;
- }
-}
-#else
-static inline int compat_try_to_freeze(void) { return 0; }
-#endif
-
-/*
- * As of 2.6.23-rc1, kernel threads are no longer freezable by
- * default. Instead, kernel threads that need to be frozen must opt-in
- * by calling set_freezable() as soon as the thread is created.
- */
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
-#define compat_set_freezable() do { set_freezable(); } while (0)
-#else
-#define compat_set_freezable() do {} while (0)
-#endif
-
-/*
- * Around 2.6.27 kernel stopped sending signals to kernel
- * threads being frozen, instead threads have to check
- * freezing() or use wait_event_freezable(). Unfortunately
- * wait_event_freezable() completely hides the fact that
- * thread was frozen from calling code and sometimes we do
- * want to know that.
- */
-#ifdef PF_FREEZER_NOSIG
-#define compat_wait_check_freezing() freezing(current)
-#else
-#define compat_wait_check_freezing() (0)
-#endif
-
-/*
- * Since 2.6.27-rc2 kill_proc() is gone... Replacement (GPL-only!)
- * API is available since 2.6.19. Use them from 2.6.27-rc1 up.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-typedef int compat_pid;
-#define compat_find_get_pid(pid) (pid)
-#define compat_put_pid(pid) do { } while (0)
-#define compat_kill_pid(pid, sig, flag) kill_proc(pid, sig, flag)
-#else
-typedef struct pid * compat_pid;
-#define compat_find_get_pid(pid) find_get_pid(pid)
-#define compat_put_pid(pid) put_pid(pid)
-#define compat_kill_pid(pid, sig, flag) kill_pid(pid, sig, flag)
-#endif
-
-
-#endif /* __COMPAT_SCHED_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SEMAPHORE_H__
-# define __COMPAT_SEMAPHORE_H__
-
-
-/* <= 2.6.25 have asm only, 2.6.26 has both, and 2.6.27-rc2+ has linux only. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-# include <asm/semaphore.h>
-#else
-# include <linux/semaphore.h>
-#endif
-
-
-/*
-* The init_MUTEX_LOCKED() API appeared in 2.2.18, and is also in
-* 2.2.17-21mdk --hpreg
-*/
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
- #ifndef init_MUTEX_LOCKED
- #define init_MUTEX_LOCKED(_sem) *(_sem) = MUTEX_LOCKED
- #endif
- #ifndef DECLARE_MUTEX
- #define DECLARE_MUTEX(name) struct semaphore name = MUTEX
- #endif
- #ifndef DECLARE_MUTEX_LOCKED
- #define DECLARE_MUTEX_LOCKED(name) struct semaphore name = MUTEX_LOCKED
- #endif
-#endif
-
-
-#endif /* __COMPAT_SEMAPHORE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SLAB_H__
-# define __COMPAT_SLAB_H__
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# include <linux/slab.h>
-#else
-# include <linux/malloc.h>
-#endif
-
-/*
- * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache
- * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and
- * afterwards it was renamed to kmem_cache. Here we keep things simple and use
- * the accepted typedef until it became deprecated, at which point we switch
- * over to the kmem_cache name.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-# define compat_kmem_cache struct kmem_cache
-#else
-# define compat_kmem_cache kmem_cache_t
-#endif
-
-/*
- * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags,
- * constructor, and destructor. Then for some time kernel was asserting that
- * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5
- * arguments - destructor is gone.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR)
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor, NULL)
-#else
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor)
-#endif
-
-/*
- * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to
- * prepare (aka "this"), from which cache it came, and some unused flags. After
- * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped...
- * Since 2.6.27-rc2 everything is different again, and ctor has only one argument.
- *
- * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_3_ARGS
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_2_ARGS
-#endif
-
-#if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \
- compat_kmem_cache *cache, \
- unsigned long flags
-#elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \
- void *arg
-#else
-typedef void compat_kmem_cache_ctor(void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg
-#endif
-
-#endif /* __COMPAT_SLAB_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SPINLOCK_H__
-# define __COMPAT_SPINLOCK_H__
-
-
-/*
- * The spin_lock() API appeared in 2.1.25 in asm/smp_lock.h
- * It moved in 2.1.30 to asm/spinlock.h
- * It moved again in 2.3.18 to linux/spinlock.h
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 18)
-# include <linux/spinlock.h>
-#else
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30)
-# include <asm/spinlock.h>
-# else
-typedef struct {} spinlock_t;
-# define spin_lock_init(lock)
-# define spin_lock(lock)
-# define spin_unlock(lock)
-# define spin_lock_irqsave(lock, flags) do { \
- save_flags(flags); \
- cli(); \
- spin_lock(lock); \
- } while (0)
-# define spin_unlock_irqrestore(lock, flags) do { \
- spin_unlock(lock); \
- restore_flags(flags); \
- } while (0)
-# endif
-#endif
-
-
-/*
- * Preempt support was added during 2.5.x development cycle, and later
- * it was backported to 2.4.x. In 2.4.x backport these definitions
- * live in linux/spinlock.h, that's why we put them here (in 2.6.x they
- * are defined in linux/preempt.h which is included by linux/spinlock.h).
- */
-#ifdef CONFIG_PREEMPT
-#define compat_preempt_disable() preempt_disable()
-#define compat_preempt_enable() preempt_enable()
-#else
-#define compat_preempt_disable() do { } while (0)
-#define compat_preempt_enable() do { } while (0)
-#endif
-
-
-#endif /* __COMPAT_SPINLOCK_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_UACCESS_H__
-# define __COMPAT_UACCESS_H__
-
-
-/* User space access functions moved in 2.1.7 to asm/uaccess.h --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 7)
-# include <asm/uaccess.h>
-#else
-# include <asm/segment.h>
-#endif
-
-
-/* get_user() API modified in 2.1.4 to take 2 arguments --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 4)
-# define compat_get_user get_user
-#else
-/*
- * We assign 0 to the variable in case of failure to prevent "`_var' might be
- * used uninitialized in this function" compiler warnings. I think it is OK,
- * because the hardware-based version in newer kernels probably has the same
- * semantics and does not guarantee that the value of _var will not be
- * modified, should the access fail --hpreg
- */
-# define compat_get_user(_var, _uvAddr) ({ \
- int _status; \
- \
- _status = verify_area(VERIFY_READ, _uvAddr, sizeof(*(_uvAddr))); \
- if (_status == 0) { \
- (_var) = get_user(_uvAddr); \
- } else { \
- (_var) = 0; \
- } \
- _status; \
-})
-#endif
-
-
-/*
- * The copy_from_user() API appeared in 2.1.4
- *
- * The emulation is not perfect here, but it is conservative: on failure, we
- * always return the total size, instead of the potentially smaller faulty
- * size --hpreg
- *
- * Since 2.5.55 copy_from_user() is no longer macro.
- */
-#if !defined(copy_from_user) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-# define copy_from_user(_to, _from, _size) ( \
- verify_area(VERIFY_READ, _from, _size) \
- ? (_size) \
- : (memcpy_fromfs(_to, _from, _size), 0) \
-)
-# define copy_to_user(_to, _from, _size) ( \
- verify_area(VERIFY_WRITE, _to, _size) \
- ? (_size) \
- : (memcpy_tofs(_to, _from, _size), 0) \
-)
-#endif
-
-
-#endif /* __COMPAT_UACCESS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_WAIT_H__
-# define __COMPAT_WAIT_H__
-
-
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/file.h>
-
-#include "compat_file.h"
-
-
-/*
- * The DECLARE_WAITQUEUE() API appeared in 2.3.1
- * It was back ported in 2.2.18
- *
- * --hpreg
- */
-
-#ifndef DECLARE_WAITQUEUE
-
-typedef struct wait_queue *wait_queue_head_t;
-# define init_waitqueue_head(_headPtr) *(_headPtr) = NULL
-# define DECLARE_WAITQUEUE(_var, _task) \
- struct wait_queue _var = {_task, NULL, }
-
-typedef struct wait_queue wait_queue_t;
-# define init_waitqueue_entry(_wait, _task) ((_wait)->task = (_task))
-
-#endif
-
-/*
- * The 'struct poll_wqueues' appeared in 2.5.48, when global
- * /dev/epoll interface was added. It was backported to the
- * 2.4.20-wolk4.0s.
- */
-
-#ifdef VMW_HAVE_EPOLL // {
-#define compat_poll_wqueues struct poll_wqueues
-#else // } {
-#define compat_poll_wqueues poll_table
-#endif // }
-
-#ifdef VMW_HAVE_EPOLL // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- poll_initwait((table)), \
- (wait) = &(table)->pt \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), \
- poll_initwait(wait) \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#else // } {
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), /* confuse compiler */ \
- (wait) = (poll_table *) __get_free_page(GFP_KERNEL), \
- (wait)->nr = 0, \
- (wait)->entry = (struct poll_table_entry *)((wait) + 1), \
- (wait)->next = NULL \
-)
-
-static inline void
-poll_freewait(poll_table *wait)
-{
- while (wait) {
- struct poll_table_entry * entry;
- poll_table *old;
-
- entry = wait->entry + wait->nr;
- while (wait->nr > 0) {
- wait->nr--;
- entry--;
- remove_wait_queue(entry->wait_address, &entry->wait);
- compat_fput(entry->filp);
- }
- old = wait;
- wait = wait->next;
- free_page((unsigned long) old);
- }
-}
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((wait)) \
-)
-
-#endif // }
-
-/*
- * The wait_event_interruptible_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_interruptible_timeout
-#define __wait_event_interruptible_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_interruptible_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_interruptible_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * The wait_event_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_timeout
-#define __wait_event_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- if (condition) \
- break; \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * DEFINE_WAIT() and friends were added in 2.5.39 and backported to 2.4.28.
- *
- * Unfortunately it is not true. While some distros may have done it the
- * change has never made it into vanilla 2.4 kernel. Instead of testing
- * particular kernel versions let's just test for presence of DEFINE_WAIT
- * when figuring out whether we need to provide replacement implementation
- * or simply alias existing one.
- */
-
-#ifndef DEFINE_WAIT
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DECLARE_WAITQUEUE(_wait, current)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- add_wait_queue(_sleep, _wait); \
- } while (0)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- set_current_state(_state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- remove_wait_queue(_sleep, _wait); \
- } while (0)
-
-#else
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DEFINE_WAIT(_wait)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- finish_wait(_sleep, _wait)
-
-#endif /* #ifndef DEFINE_WAIT */
-
-#endif /* __COMPAT_WAIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_atomic.h --
- *
- * Atomic power
- */
-
-#ifndef _ATOMIC_H_
-#define _ATOMIC_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-
-
-/* Basic atomic type: 32 bits */
-typedef struct Atomic_uint32 {
- volatile uint32 value;
-} Atomic_uint32;
-
-
-/* Basic atomic type: 64 bits */
-typedef struct Atomic_uint64 {
- volatile uint64 value;
-} Atomic_uint64 ALIGNED(8);
-
-
-/*
- * Prototypes for msft atomics. These are defined & inlined by the
- * compiler so no function definition is needed. The prototypes are
- * needed for c++. Since amd64 compiler doesn't support inline asm we
- * have to use these. Unfortunately, we still have to use some inline asm
- * for the 32 bit code since the and/or/xor implementations didn't show up
- * untill xp or 2k3.
- *
- * The declarations for the intrinsic functions were taken from ntddk.h
- * in the DDK. The declarations must match otherwise the 64-bit c++
- * compiler will complain about second linkage of the intrinsic functions.
- * We define the intrinsic using the basic types corresponding to the
- * Windows typedefs. This avoids having to include windows header files
- * to get to the windows types.
- */
-#if defined(_MSC_VER) && _MSC_VER >= 1310
-#ifdef __cplusplus
-extern "C" {
-#endif
-long _InterlockedExchange(long volatile*, long);
-long _InterlockedCompareExchange(long volatile*, long, long);
-long _InterlockedExchangeAdd(long volatile*, long);
-long _InterlockedDecrement(long volatile*);
-long _InterlockedIncrement(long volatile*);
-#pragma intrinsic(_InterlockedExchange, _InterlockedCompareExchange)
-#pragma intrinsic(_InterlockedExchangeAdd, _InterlockedDecrement)
-#pragma intrinsic(_InterlockedIncrement)
-
-#if defined(VM_X86_64)
-long _InterlockedAnd(long volatile*, long);
-__int64 _InterlockedAnd64(__int64 volatile*, __int64);
-long _InterlockedOr(long volatile*, long);
-__int64 _InterlockedOr64(__int64 volatile*, __int64);
-long _InterlockedXor(long volatile*, long);
-__int64 _InterlockedXor64(__int64 volatile*, __int64);
-__int64 _InterlockedExchangeAdd64(__int64 volatile*, __int64);
-__int64 _InterlockedIncrement64(__int64 volatile*);
-__int64 _InterlockedDecrement64(__int64 volatile*);
-__int64 _InterlockedExchange64(__int64 volatile*, __int64);
-__int64 _InterlockedCompareExchange64(__int64 volatile*, __int64, __int64);
-#if !defined(_WIN64)
-#pragma intrinsic(_InterlockedAnd, _InterlockedAnd64)
-#pragma intrinsic(_InterlockedOr, _InterlockedOr64)
-#pragma intrinsic(_InterlockedXor, _InterlockedXor64)
-#pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedIncrement64)
-#pragma intrinsic(_InterlockedDecrement64, _InterlockedExchange64)
-#pragma intrinsic(_InterlockedCompareExchange64)
-#endif /* !_WIN64 */
-#endif /* __x86_64__ */
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _MSC_VER */
-
-
-/* Convert a volatile int to Atomic_uint32. */
-static INLINE Atomic_uint32 *
-Atomic_VolatileToAtomic(volatile uint32 *var)
-{
- return (Atomic_uint32 *)var;
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Init, Atomic_SetFence, AtomicUseFence --
- *
- * Determine whether an lfence intruction is executed after
- * every locked instruction.
- *
- * Certain AMD processes have a bug (see bug 107024) that
- * requires an lfence after every locked instruction.
- *
- * The global variable AtomicUseFence controls whether lfence
- * is used (see AtomicEpilogue).
- *
- * Atomic_SetFence sets AtomicUseFence to the given value.
- *
- * Atomic_Init computes and sets AtomicUseFence.
- * It does not take into account the number of processors.
- *
- * The rationale for all this complexity is that Atomic_Init
- * is the easy-to-use interface. It can be called a number
- * of times cheaply, and does not depend on other libraries.
- * However, because the number of CPUs is difficult to compute,
- * it does without it and always assumes there are more than one.
- *
- * For programs that care or have special requirements,
- * Atomic_SetFence can be called directly, in addition to Atomic_Init.
- * It overrides the effect of Atomic_Init, and can be called
- * before, after, or between calls to Atomic_Init.
- *
- *-----------------------------------------------------------------------------
- */
-
-// The freebsd assembler doesn't know the lfence instruction
-#if defined(__GNUC__) && \
- __GNUC__ >= 3 && \
- (defined(__VMKERNEL__) || !defined(__FreeBSD__)) && \
- (!defined(MODULE) || defined(__VMKERNEL_MODULE__)) && \
- !defined(__APPLE__) /* PR136775 */
-#define ATOMIC_USE_FENCE
-#endif
-
-#if defined(VMATOMIC_IMPORT_DLLDATA)
-VMX86_EXTERN_DATA Bool AtomicUseFence;
-#else
-EXTERN Bool AtomicUseFence;
-#endif
-
-EXTERN Bool atomicFenceInitialized;
-
-void AtomicInitFence(void);
-
-static INLINE void
-Atomic_Init(void)
-{
-#ifdef ATOMIC_USE_FENCE
- if (!atomicFenceInitialized) {
- AtomicInitFence();
- }
-#endif
-}
-
-static INLINE void
-Atomic_SetFence(Bool fenceAfterLock) /* IN: TRUE to enable lfence */
- /* FALSE to disable. */
-{
- AtomicUseFence = fenceAfterLock;
-#if defined(__VMKERNEL__)
- extern void Atomic_SetFenceVMKAPI(Bool fenceAfterLock);
- Atomic_SetFenceVMKAPI(fenceAfterLock);
-#endif
- atomicFenceInitialized = TRUE;
-}
-
-
-/* Conditionally execute fence after interlocked instruction. */
-static INLINE void
-AtomicEpilogue(void)
-{
-#ifdef ATOMIC_USE_FENCE
-#ifdef VMM
- /* The monitor conditionally patches out the lfence when not needed.*/
- /* Construct a MonitorPatchTextEntry in the .patchtext section. */
- asm volatile ("1:\n\t"
- "lfence\n\t"
- "2:\n\t"
- ".pushsection .patchtext\n\t"
-#ifdef VMM32
- ".long 1b\n\t"
- ".long 0\n\t"
- ".long 2b\n\t"
- ".long 0\n\t"
-#else
- ".quad 1b\n\t"
- ".quad 2b\n\t"
-#endif
- ".popsection\n\t" ::: "memory");
-#else
- if (UNLIKELY(AtomicUseFence)) {
- asm volatile ("lfence" ::: "memory");
- }
-#endif
-#endif
-}
-
-
-/*
- * All the assembly code is tricky and written conservatively.
- * For example, to make sure gcc won't introduce copies,
- * we force the addressing mode like this:
- *
- * "xchgl %0, (%1)"
- * : "=r" (val)
- * : "r" (&var->value),
- * "0" (val)
- * : "memory"
- *
- * - edward
- *
- * Actually - turns out that gcc never generates memory aliases (it
- * still does generate register aliases though), so we can be a bit
- * more agressive with the memory constraints. The code above can be
- * modified like this:
- *
- * "xchgl %0, %1"
- * : "=r" (val),
- * "=m" (var->value),
- * : "0" (val),
- * "1" (var->value)
- *
- * The advantages are that gcc can use whatever addressing mode it
- * likes to access the memory value, and that we dont have to use a
- * way-too-generic "memory" clobber as there is now an explicit
- * declaration that var->value is modified.
- *
- * see also /usr/include/asm/atomic.h to convince yourself this is a
- * valid optimization.
- *
- * - walken
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Read --
- *
- * Read
- *
- * Results:
- * The value of the atomic variable.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_Read(Atomic_uint32 const *var) // IN
-{
- return var->value;
-}
-#define Atomic_Read32 Atomic_Read
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Write --
- *
- * Write
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Write(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
- var->value = val;
-}
-#define Atomic_Write32 Atomic_Write
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadWrite --
- *
- * Read followed by write
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_ReadWrite(Atomic_uint32 *var, // IN
- uint32 val) // IN
-#ifdef __GNUC__
-{
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "xchgl %0, %1"
-# if VM_ASM_PLUS
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
-# else
- : "=r" (val),
- "=m" (var->value)
- : "0" (val),
- "1" (var->value)
-# endif
- );
- AtomicEpilogue();
- return val;
-}
-#elif _MSC_VER >= 1310
-{
- return _InterlockedExchange((long *)&var->value, (long)val);
-}
-#elif _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov eax, val
- __asm mov ebx, var
- __asm xchg [ebx]Atomic_uint32.value, eax
- // eax is the return value, this is documented to work - edward
-}
-#pragma warning(pop)
-#else
-#error No compiler defined for Atomic_ReadWrite
-#endif
-#define Atomic_ReadWrite32 Atomic_ReadWrite
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadIfEqualWrite --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * The variable may be modified.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_ReadIfEqualWrite(Atomic_uint32 *var, // IN
- uint32 oldVal, // IN
- uint32 newVal) // IN
-#ifdef __GNUC__
-{
- uint32 val;
-
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; cmpxchgl %2, %1"
-# if VM_ASM_PLUS
- : "=a" (val),
- "+m" (var->value)
- : "r" (newVal),
- "0" (oldVal)
-# else
- : "=a" (val),
- "=m" (var->value)
- : "r" (newVal),
- "0" (oldVal)
- /*
- * "1" (var->value): results in inconsistent constraints on gcc 2.7.2.3
- * when compiling enterprise-2.2.17-14-RH7.0-update.
- * The constraint has been commented out for now. We may consider doing
- * this systematically, but we need to be sure it is the right thing to
- * do. However, it is also possible that the offending use of this asm
- * function will be removed in the near future in which case we may
- * decide to reintroduce the constraint instead. hpreg & agesen.
- */
-# endif
- : "cc"
- );
- AtomicEpilogue();
- return val;
-}
-#elif _MSC_VER >= 1310
-{
- return _InterlockedCompareExchange((long *)&var->value,
- (long)newVal,
- (long)oldVal);
-}
-#elif _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov eax, oldVal
- __asm mov ebx, var
- __asm mov ecx, newVal
- __asm lock cmpxchg [ebx]Atomic_uint32.value, ecx
- // eax is the return value, this is documented to work - edward
-}
-#pragma warning(pop)
-#else
-#error No compiler defined for Atomic_ReadIfEqualWrite
-#endif
-#define Atomic_ReadIfEqualWrite32 Atomic_ReadIfEqualWrite
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadIfEqualWrite64 --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * The variable may be modified.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadIfEqualWrite64(Atomic_uint64 *var, // IN
- uint64 oldVal, // IN
- uint64 newVal) // IN
-{
-#if defined(__GNUC__)
- uint64 val;
-
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; cmpxchgq %2, %1"
- : "=a" (val),
- "+m" (var->value)
- : "r" (newVal),
- "0" (oldVal)
- : "cc"
- );
- AtomicEpilogue();
- return val;
-#elif _MSC_VER
- return _InterlockedCompareExchange64((__int64 *)&var->value,
- (__int64)newVal,
- (__int64)oldVal);
-#else
-#error No compiler defined for Atomic_ReadIfEqualWrite64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_And --
- *
- * Atomic read, bitwise AND with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_And(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; andl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
-#if defined(__x86_64__)
- _InterlockedAnd((long *)&var->value, (long)val);
-#else
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock and [ebx]Atomic_uint32.value, eax
-#endif
-#else
-#error No compiler defined for Atomic_And
-#endif
-}
-#define Atomic_And32 Atomic_And
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_And64 --
- *
- * Atomic read, bitwise AND with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_And64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; andq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedAnd64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_And64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Or --
- *
- * Atomic read, bitwise OR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Or(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; orl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
-#if defined(__x86_64__)
- _InterlockedOr((long *)&var->value, (long)val);
-#else
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock or [ebx]Atomic_uint32.value, eax
-#endif
-#else
-#error No compiler defined for Atomic_Or
-#endif
-}
-#define Atomic_Or32 Atomic_Or
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Or64 --
- *
- * Atomic read, bitwise OR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Or64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; orq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedOr64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_Or64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Xor --
- *
- * Atomic read, bitwise XOR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Xor(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; xorl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
-#if defined(__x86_64__)
- _InterlockedXor((long *)&var->value, (long)val);
-#else
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock xor [ebx]Atomic_uint32.value, eax
-#endif
-#else
-#error No compiler defined for Atomic_Xor
-#endif
-}
-#define Atomic_Xor32 Atomic_Xor
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Xor64 --
- *
- * Atomic read, bitwise XOR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Xor64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; xorq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedXor64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_Xor64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Add --
- *
- * Atomic read, add a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Add(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; addl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedExchangeAdd((long *)&var->value, (long)val);
-#elif _MSC_VER
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock add [ebx]Atomic_uint32.value, eax
-#else
-#error No compiler defined for Atomic_Add
-#endif
-}
-#define Atomic_Add32 Atomic_Add
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Add64 --
- *
- * Atomic read, add a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Add64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; addq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_Add64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Sub --
- *
- * Atomic read, subtract a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Sub(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; subl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedExchangeAdd((long *)&var->value, (long)-val);
-#elif _MSC_VER
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock sub [ebx]Atomic_uint32.value, eax
-#else
-#error No compiler defined for Atomic_Sub
-#endif
-}
-#define Atomic_Sub32 Atomic_Sub
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Sub64 --
- *
- * Atomic read, subtract a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Sub64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; subq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)-val);
-#else
-#error No compiler defined for Atomic_Sub64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Inc --
- *
- * Atomic read, increment, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Inc(Atomic_uint32 *var) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; incl %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- :
-# else
- : "=m" (var->value)
- : "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedIncrement((long *)&var->value);
-#elif _MSC_VER
- __asm mov ebx, var
- __asm lock inc [ebx]Atomic_uint32.value
-#else
-#error No compiler defined for Atomic_Inc
-#endif
-}
-#define Atomic_Inc32 Atomic_Inc
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Inc64 --
- *
- * Atomic read, increment, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Inc64(Atomic_uint64 *var) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; incq %0"
- : "+m" (var->value)
- :
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedIncrement64((__int64 *)&var->value);
-#else
-#error No compiler defined for Atomic_Inc64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Dec --
- *
- * Atomic read, decrement, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Dec(Atomic_uint32 *var) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; decl %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- :
-# else
- : "=m" (var->value)
- : "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedDecrement((long *)&var->value);
-#elif _MSC_VER
- __asm mov ebx, var
- __asm lock dec [ebx]Atomic_uint32.value
-#else
-#error No compiler defined for Atomic_Dec
-#endif
-}
-#define Atomic_Dec32 Atomic_Dec
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Dec64 --
- *
- * Atomic read, decrement, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Dec64(Atomic_uint64 *var) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; decq %0"
- : "+m" (var->value)
- :
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedDecrement64((__int64 *)&var->value);
-#else
-#error No compiler defined for Atomic_Dec64
-#endif
-}
-#endif
-
-
-/*
- * Note that the technique below can be used to implement ReadX(), where X is
- * an arbitrary mathematical function.
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndOr --
- *
- * Atomic read (returned), bitwise OR with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndOr(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
- uint32 res;
-
- do {
- res = var->value;
- } while (res != Atomic_ReadIfEqualWrite(var, res, res | val));
-
- return res;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndAnd --
- *
- * Atomic read (returned), bitwise And with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndAnd(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
- uint32 res;
-
- do {
- res = var->value;
- } while (res != Atomic_ReadIfEqualWrite(var, res, res & val));
-
- return res;
-}
-#define Atomic_ReadOr32 Atomic_FetchAndOr
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadOr64 --
- *
- * Atomic read (returned), bitwise OR with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadOr64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
- uint64 res;
-
- do {
- res = var->value;
- } while (res != Atomic_ReadIfEqualWrite64(var, res, res | val));
-
- return res;
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndAddUnfenced --
- *
- * Atomic read (returned), add a value, write.
- *
- * If you have to implement FetchAndAdd() on an architecture other than
- * x86 or x86-64, you might want to consider doing something similar to
- * Atomic_FetchAndOr().
- *
- * The "Unfenced" version of Atomic_FetchAndInc never executes
- * "lfence" after the interlocked operation.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndAddUnfenced(Atomic_uint32 *var, // IN
- uint32 val) // IN
-#ifdef __GNUC__
-{
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
-# if VM_ASM_PLUS
- "lock; xaddl %0, %1"
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
- : "cc"
-# else
- "lock; xaddl %0, (%1)"
- : "=r" (val)
- : "r" (&var->value),
- "0" (val)
- : "cc", "memory"
-# endif
- );
- return val;
-}
-#elif _MSC_VER >= 1310
-{
- return _InterlockedExchangeAdd((long *)&var->value, (long)val);
-}
-#elif _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock xadd [ebx]Atomic_uint32.value, eax
-}
-#pragma warning(pop)
-#else
-#error No compiler defined for Atomic_FetchAndAdd
-#endif
-#define Atomic_ReadAdd32 Atomic_FetchAndAdd
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndAdd --
- *
- * Atomic read (returned), add a value, write.
- *
- * If you have to implement FetchAndAdd() on an architecture other than
- * x86 or x86-64, you might want to consider doing something similar to
- * Atomic_FetchAndOr().
- *
- * Unlike "Unfenced" version, this one may execute the "lfence" after
- * interlocked operation.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndAdd(Atomic_uint32 *var, // IN
- uint32 val) // IN
-#ifdef __GNUC__
-{
- val = Atomic_FetchAndAddUnfenced(var, val);
- AtomicEpilogue();
- return val;
-}
-#else
-{
- return Atomic_FetchAndAddUnfenced(var, val);
-}
-#endif
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadAdd64 --
- *
- * Atomic read (returned), add a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadAdd64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; xaddq %0, %1"
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
- : "cc"
- );
- AtomicEpilogue();
- return val;
-#elif _MSC_VER
- return _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_ReadAdd64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndInc --
- *
- * Atomic read (returned), increment, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndInc(Atomic_uint32 *var) // IN
-{
- return Atomic_FetchAndAdd(var, 1);
-}
-#define Atomic_ReadInc32 Atomic_FetchAndInc
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadInc64 --
- *
- * Atomic read (returned), increment, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadInc64(Atomic_uint64 *var) // IN
-{
- return Atomic_ReadAdd64(var, 1);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndDec --
- *
- * Atomic read (returned), decrement, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndDec(Atomic_uint32 *var) // IN
-{
- return Atomic_FetchAndAdd(var, (uint32)-1);
-}
-#define Atomic_ReadDec32 Atomic_FetchAndDec
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadDec64 --
- *
- * Atomic read (returned), decrement, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadDec64(Atomic_uint64 *var) // IN
-{
- return Atomic_ReadAdd64(var, CONST64U(-1));
-}
-#endif
-
-
-#ifdef VMKERNEL
-/*
- *-----------------------------------------------------------------------------
- *
- * CMPXCHG1B --
- *
- * Compare and exchange a single byte.
- *
- * Results:
- * The value read from ptr.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-static INLINE uint8
-CMPXCHG1B(volatile uint8 *ptr, // IN
- uint8 oldVal, // IN
- uint8 newVal) // IN
-{
- uint8 val;
- __asm__ __volatile__("lock; cmpxchgb %b2, %1"
- : "=a" (val),
- "+m" (*ptr)
- : "r" (newVal),
- "0" (oldVal)
- : "cc");
- return val;
-}
-#endif
-
-
-/*
- * Usage of this helper struct is strictly reserved to the following
- * function. --hpreg
- */
-typedef struct {
- uint32 lowValue;
- uint32 highValue;
-} S_uint64;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_CMPXCHG64 --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * XXX: Ensure that if this function is to be inlined by gcc, it is
- * compiled with -fno-strict-aliasing. Otherwise it will break.
- * Unfortunately we know that gcc 2.95.3 (used to build the FreeBSD 3.2
- * Tools) does not honor -fno-strict-aliasing. As a workaround, we avoid
- * inlining the function entirely for versions of gcc under 3.0.
- *
- * Results:
- * TRUE if equal, FALSE if not equal
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__) && __GNUC__ < 3
-static Bool
-#else
-static INLINE Bool
-#endif
-Atomic_CMPXCHG64(Atomic_uint64 *var, // IN/OUT
- uint64 const *oldVal, // IN
- uint64 const *newVal) // IN
-#ifdef __GNUC__
-{
- Bool equal;
-
- /* Checked against the Intel manual and GCC --walken */
-#ifdef VMM64
- uint64 dummy;
- __asm__ __volatile__(
- "lock; cmpxchgq %3, %0" "\n\t"
- "sete %1"
- : "+m" (*var),
- "=qm" (equal),
- "=a" (dummy)
- : "r" (*newVal),
- "2" (*oldVal)
- : "cc"
- );
-#else /* 32-bit version */
- int dummy1, dummy2;
-# if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
-# if defined __GNUC__ && __GNUC__ < 3 // Part of #188541 - for RHL 6.2 etc.
- __asm__ __volatile__(
- "xchg %%ebx, %6\n\t"
- "mov (%%ebx), %%ecx\n\t"
- "mov (%%ebx), %%ebx\n\t"
- "lock; cmpxchg8b (%3)\n\t"
- "xchg %%ebx, %6\n\t"
- "sete %0"
- : "=a" (equal), "=d" (dummy2), "=D" (dummy1)
- : "S" (var), "0" (((S_uint64 const *)oldVal)->lowValue),
- "1" (((S_uint64 const *)oldVal)->highValue), "D" (newVal)
- : "ecx", "cc", "memory"
- );
-# else
- __asm__ __volatile__(
- "xchgl %%ebx, %6" "\n\t"
- // %3 is a register to make sure it cannot be %ebx-relative.
- "lock; cmpxchg8b (%3)" "\n\t"
- "xchgl %%ebx, %6" "\n\t"
- // Must come after restoring %ebx: %0 could be %ebx-relative.
- "sete %0"
- : "=qm" (equal),
- "=a" (dummy1),
- "=d" (dummy2)
- : "r" (var),
- "1" (((S_uint64 const *)oldVal)->lowValue),
- "2" (((S_uint64 const *)oldVal)->highValue),
- // Cannot use "m" here: 'newVal' is read-only.
- "r" (((S_uint64 const *)newVal)->lowValue),
- "c" (((S_uint64 const *)newVal)->highValue)
- : "cc", "memory"
- );
-# endif
-# else
- __asm__ __volatile__(
- "lock; cmpxchg8b %0" "\n\t"
- "sete %1"
-# if VM_ASM_PLUS
- : "+m" (*var),
-# else
- : "=m" (*var),
-# endif
- "=qm" (equal),
- "=a" (dummy1),
- "=d" (dummy2)
- : "2" (((S_uint64 const *)oldVal)->lowValue),
- "3" (((S_uint64 const *)oldVal)->highValue),
- "b" (((S_uint64 const *)newVal)->lowValue),
- "c" (((S_uint64 const *)newVal)->highValue)
- : "cc"
- );
-# endif
-#endif
- AtomicEpilogue();
- return equal;
-}
-#elif _MSC_VER
-#if defined(__x86_64__)
-{
- return *oldVal == _InterlockedCompareExchange64((__int64 *)&var->value,
- (__int64)*newVal,
- (__int64)*oldVal);
-}
-#else
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov esi, var
- __asm mov edx, oldVal
- __asm mov ecx, newVal
- __asm mov eax, [edx]S_uint64.lowValue
- __asm mov edx, [edx]S_uint64.highValue
- __asm mov ebx, [ecx]S_uint64.lowValue
- __asm mov ecx, [ecx]S_uint64.highValue
- __asm lock cmpxchg8b [esi]
- __asm sete al
- __asm movzx eax, al
- // eax is the return value, this is documented to work - edward
-}
-#pragma warning(pop)
-#endif
-#else
-#error No compiler defined for Atomic_CMPXCHG64
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_CMPXCHG32 --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * Results:
- * TRUE if equal, FALSE if not equal
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-Atomic_CMPXCHG32(Atomic_uint32 *var, // IN/OUT
- uint32 oldVal, // IN
- uint32 newVal) // IN
-{
-#ifdef __GNUC__
- Bool equal;
-
- uint32 dummy;
- __asm__ __volatile__(
- "lock; cmpxchgl %3, %0" "\n\t"
- "sete %1"
-# if VM_ASM_PLUS
- : "+m" (*var),
- "=qm" (equal),
- "=a" (dummy)
- : "r" (newVal),
- "2" (oldVal)
-# else
- : "=m" (*var),
- "=qm" (equal),
- "=a" (dummy)
- : /*"0" (*var), */
- "r" (newVal),
- "2" (oldVal)
-# endif
- : "cc"
- );
- AtomicEpilogue();
- return equal;
-#else
- return (Atomic_ReadIfEqualWrite(var, oldVal, newVal) == oldVal);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Read64 --
- *
- * Read and return.
- *
- * Results:
- * The value of the atomic variable.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_Read64(Atomic_uint64 const *var) // IN
-#if defined(__x86_64__)
-{
- return var->value;
-}
-#elif defined(__GNUC__) && defined(__i386__) /* GCC on x86 */
-{
- uint64 value;
- /*
- * Since cmpxchg8b will replace the contents of EDX:EAX with the
- * value in memory if there is no match, we need only execute the
- * instruction once in order to atomically read 64 bits from
- * memory. The only constraint is that ECX:EBX must have the same
- * value as EDX:EAX so that if the comparison succeeds. We
- * intentionally don't tell gcc that we are using ebx and ecx as we
- * don't modify them and do not care what value they store.
- */
- __asm__ __volatile__(
- "mov %%ebx, %%eax" "\n\t"
- "mov %%ecx, %%edx" "\n\t"
- "lock; cmpxchg8b %1"
- : "=&A" (value)
- : "m" (*var)
- : "cc"
- );
- AtomicEpilogue();
- return value;
-}
-#elif _MSC_VER /* MSC (assume on x86 for now) */
-# pragma warning(push)
-# pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov ecx, var
- __asm mov edx, ecx
- __asm mov eax, ebx
- __asm lock cmpxchg8b [ecx]
- // edx:eax is the return value; this is documented to work. --mann
-}
-# pragma warning(pop)
-#else
-# error No compiler defined for Atomic_Read64
-#endif
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Atomic_FetchAndAdd64 --
- *
- * Atomically adds a 64-bit integer to another
- *
- * Results:
- * Returns the old value just prior to the addition
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_FetchAndAdd64(Atomic_uint64 *var, // IN/OUT
- uint64 addend) // IN
-{
- uint64 oldVal;
- uint64 newVal;
-
- do {
- oldVal = var->value;
- newVal = oldVal + addend;
- } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal));
-
- return oldVal;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Atomic_FetchAndInc64 --
- *
- * Atomically increments a 64-bit integer
- *
- * Results:
- * Returns the old value just prior to incrementing
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_FetchAndInc64(Atomic_uint64 *var) // IN/OUT
-{
- return Atomic_FetchAndAdd64(var, 1);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Atomic_FetchAndDec64 --
- *
- * Atomically decrements a 64-bit integer
- *
- * Results:
- * Returns the old value just prior to decrementing
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_FetchAndDec64(Atomic_uint64 *var) // IN/OUT
-{
- uint64 oldVal;
- uint64 newVal;
-
- do {
- oldVal = var->value;
- newVal = oldVal - 1;
- } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal));
-
- return oldVal;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadWrite64 --
- *
- * Read followed by write
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadWrite64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__x86_64__)
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "xchgq %0, %1"
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
- );
- AtomicEpilogue();
- return val;
-#elif _MSC_VER
- return _InterlockedExchange64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_ReadWrite64
-#endif
-#else
- uint64 oldVal;
-
- do {
- oldVal = var->value;
- } while (!Atomic_CMPXCHG64(var, &oldVal, &val));
-
- return oldVal;
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Write64 --
- *
- * Write
- *
- * Results:
- * None.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Write64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__x86_64__)
- var->value = val;
-#else
- (void)Atomic_ReadWrite64(var, val);
-#endif
-}
-
-
-/*
- * Template code for the Atomic_<name> type and its operators.
- *
- * The cast argument is an intermedia type cast to make some
- * compilers stop complaining about casting uint32 <-> void *,
- * even though we only do it in the 32-bit case so they are always
- * the same size. So for val of type uint32, instead of
- * (void *)val, we have (void *)(uintptr_t)val.
- * The specific problem case is the Windows ddk compiler
- * (as used by the SVGA driver). -- edward
- */
-
-#define MAKE_ATOMIC_TYPE(name, size, in, out, cast) \
- typedef Atomic_uint ## size Atomic_ ## name; \
- \
- \
- static INLINE out \
- Atomic_Read ## name(Atomic_ ## name const *var) \
- { \
- return (out)(cast)Atomic_Read ## size(var); \
- } \
- \
- \
- static INLINE void \
- Atomic_Write ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Write ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadWrite ## name(Atomic_ ## name *var, \
- in val) \
- { \
- return (out)(cast)Atomic_ReadWrite ## size(var, \
- (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadIfEqualWrite ## name(Atomic_ ## name *var, \
- in oldVal, \
- in newVal) \
- { \
- return (out)(cast)Atomic_ReadIfEqualWrite ## size(var, \
- (uint ## size)(cast)oldVal, (uint ## size)(cast)newVal); \
- } \
- \
- \
- static INLINE void \
- Atomic_And ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_And ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Or ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Or ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Xor ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Xor ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Add ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Add ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Sub ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Sub ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Inc ## name(Atomic_ ## name *var) \
- { \
- Atomic_Inc ## size(var); \
- } \
- \
- \
- static INLINE void \
- Atomic_Dec ## name(Atomic_ ## name *var) \
- { \
- Atomic_Dec ## size(var); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadOr ## name(Atomic_ ## name *var, \
- in val) \
- { \
- return (out)(cast)Atomic_ReadOr ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadAdd ## name(Atomic_ ## name *var, \
- in val) \
- { \
- return (out)(cast)Atomic_ReadAdd ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadInc ## name(Atomic_ ## name *var) \
- { \
- return (out)(cast)Atomic_ReadInc ## size(var); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadDec ## name(Atomic_ ## name *var) \
- { \
- return (out)(cast)Atomic_ReadDec ## size(var); \
- }
-
-
-/*
- * Since we use a macro to generate these definitions, it is hard to look for
- * them. So DO NOT REMOVE THIS COMMENT and keep it up-to-date. --hpreg
- *
- * Atomic_Ptr
- * Atomic_ReadPtr --
- * Atomic_WritePtr --
- * Atomic_ReadWritePtr --
- * Atomic_ReadIfEqualWritePtr --
- * Atomic_AndPtr --
- * Atomic_OrPtr --
- * Atomic_XorPtr --
- * Atomic_AddPtr --
- * Atomic_SubPtr --
- * Atomic_IncPtr --
- * Atomic_DecPtr --
- * Atomic_ReadOrPtr --
- * Atomic_ReadAddPtr --
- * Atomic_ReadIncPtr --
- * Atomic_ReadDecPtr --
- *
- * Atomic_Int
- * Atomic_ReadInt --
- * Atomic_WriteInt --
- * Atomic_ReadWriteInt --
- * Atomic_ReadIfEqualWriteInt --
- * Atomic_AndInt --
- * Atomic_OrInt --
- * Atomic_XorInt --
- * Atomic_AddInt --
- * Atomic_SubInt --
- * Atomic_IncInt --
- * Atomic_DecInt --
- * Atomic_ReadOrInt --
- * Atomic_ReadAddInt --
- * Atomic_ReadIncInt --
- * Atomic_ReadDecInt --
- */
-#if defined(__x86_64__)
-MAKE_ATOMIC_TYPE(Ptr, 64, void const *, void *, uintptr_t)
-MAKE_ATOMIC_TYPE(Int, 64, int, int, int)
-#else
-MAKE_ATOMIC_TYPE(Ptr, 32, void const *, void *, uintptr_t)
-MAKE_ATOMIC_TYPE(Int, 32, int, int, int)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_MFence --
- *
- * Implements mfence in terms of a lock xor. The reason for implementing
- * our own mfence is that not all of our supported cpus have an assembly
- * mfence (P3, Athlon). We put it here to avoid duplicating code which is
- * also why it is prefixed with "Atomic_".
- *
- * Results:
- * None.
- *
- * Side effects:
- * Cause loads and stores prior to this to be globally
- * visible.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_MFence(void)
-{
- Atomic_uint32 fence;
- Atomic_Xor(&fence, 0x1);
-}
-
-#endif // ifndef _ATOMIC_H_
sub->callbackData = callbackData;
VMCIEventGrabLock(&subscriberLock, &flags);
- ASSERT(subscriberArray);
for (success = FALSE, attempts = 0;
success == FALSE && attempts < VMCI_EVENT_MAX_ATTEMPTS;
attempts++) {
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
-# define VMCIKVaToMPN(__VA) page_to_pfn(vmalloc_to_page((void *)(__VA)))
+# define VMCIKVaToMPN(_ptr) page_to_pfn(vmalloc_to_page(_ptr))
#else
-# define VMCIKVaToMPN(__VA) PgtblKVa2MPN(__VA)
+# define VMCIKVaToMPN(_ptr) PgtblKVa2MPN((VA)_ptr)
#endif
/*
*/
int
-VMCI_CopyToUser(void *dst, // OUT
- const void *src, // IN
- unsigned int len) // IN
+VMCI_CopyToUser(VA64 dst, // OUT: Destination user VA.
+ const void *src, // IN: Source kernel VA.
+ size_t len) // IN: Number of bytes to copy.
{
- return copy_to_user(dst, src, len) ? -EFAULT : 0;
+ return copy_to_user(VMCIVA64ToPtr(dst), src, len) ? -EFAULT : 0;
}
*/
int
-VMCI_CopyFromUser(void *dst, // OUT
- const void *src, // IN
- size_t len) // IN
+VMCI_CopyFromUser(void *dst, // OUT: Kernel VA
+ VA64 src, // IN: User VA
+ size_t len) // IN
{
- return copy_from_user(dst, src, len);
+ return copy_from_user(dst, VMCIVA64ToPtr(src), len);
}
/*
*-----------------------------------------------------------------------------
*
- * VMCI_AllocQueueKVA --
+ * VMCI_AllocQueue --
*
* Allocates kernel memory for the queue header (1 page) plus the
* translation structure for offset -> page mappings. Allocates physical
* structure.
*
* Results:
- * The VA on success, NULL otherwise.
+ * Pointer to the queue on success, NULL otherwise.
*
* Side effects:
* Memory is allocated.
*-----------------------------------------------------------------------------
*/
-VA
-VMCI_AllocQueueKVA(uint64 size) // IN: size of queue (not including header)
+void *
+VMCI_AllocQueue(uint64 size) // IN: size of queue (not including header)
{
const uint64 numPages = CEILING(size, PAGE_SIZE);
VMCIQueue *queue;
}
}
}
- return (VA)queue;
+ return queue;
}
/*
*-----------------------------------------------------------------------------
*
- * VMCI_FreeQueueKVA --
+ * VMCI_FreeQueue --
*
* Frees kernel memory for a given queue (header plus translation
* structure). Frees all physical pages that held the buffers for this
*/
void
-VMCI_FreeQueueKVA(VA va, // IN:
- uint64 size) // IN: size of queue (not including header)
+VMCI_FreeQueue(void *q, // IN:
+ uint64 size) // IN: size of queue (not including header)
{
- VMCIQueue *queue = (VMCIQueue *)va;
+ VMCIQueue *queue = q;
if (queue) {
uint64 i;
*/
int
-VMCI_AllocPPNSet(VA produceVA, // IN:
+VMCI_AllocPPNSet(void *produceQ, // IN:
uint64 numProducePages, // IN: for queue plus header
- VA consumeVA, // IN:
+ void *consumeQ, // IN:
uint64 numConsumePages, // IN: for queue plus header
PPNSet *ppnSet) // OUT:
{
VMCIPpnList producePPNs;
VMCIPpnList consumePPNs;
uint64 i;
- VMCIQueue *produceQ = (VMCIQueue *)produceVA;
- VMCIQueue *consumeQ = (VMCIQueue *)consumeVA;
- if (!produceVA || !numProducePages || !consumeVA || !numConsumePages ||
+ if (!produceQ || !numProducePages || !consumeQ || !numConsumePages ||
!ppnSet) {
return VMCI_ERROR_INVALID_ARGS;
}
return VMCI_ERROR_NO_MEM;
}
- producePPNs[0] = VMCIKVaToMPN(produceVA);
+ producePPNs[0] = VMCIKVaToMPN(produceQ);
for (i = 1; i < numProducePages; i++) {
unsigned long pfn;
- producePPNs[i] = pfn = page_to_pfn(produceQ->page[i - 1]);
+ producePPNs[i] = pfn = page_to_pfn(((VMCIQueue *)produceQ)->page[i - 1]);
/*
* Fail allocation if PFN isn't supported by hypervisor.
goto ppnError;
}
}
- consumePPNs[0] = VMCIKVaToMPN(consumeVA);
+ consumePPNs[0] = VMCIKVaToMPN(consumeQ);
for (i = 1; i < numConsumePages; i++) {
unsigned long pfn;
- consumePPNs[i] = pfn = page_to_pfn(consumeQ->page[i - 1]);
+ consumePPNs[i] = pfn = page_to_pfn(((VMCIQueue *)consumeQ)->page[i - 1]);
/*
* Fail allocation if PFN isn't supported by hypervisor.
*/
int
-VMCIProcess_Create(VMCIProcess **outProcess, // IN
- int eventHnd) // IN
+VMCIProcess_Create(VMCIProcess **outProcess) // IN
{
VMCIProcess *process;
VMCILockFlags flags;
void VMCIProcess_Init(void);
void VMCIProcess_Exit(void);
Bool VMCIProcess_CheckHostCapabilities(void);
-int VMCIProcess_Create(VMCIProcess **outProcess, int eventHnd);
+int VMCIProcess_Create(VMCIProcess **outProcess);
void VMCIProcess_Destroy(VMCIProcess *process);
VMCIProcess *VMCIProcess_Get(VMCIId processID);
uint64 consumeSize;
uint64 numPPNs;
PPNSet ppnSet;
- VA produceQVA;
- VA consumeQVA;
+ void *produceQ;
+ void *consumeQ;
uint32 refCount;
ListItem listItem;
} QueuePairEntry;
VMCIId peer, uint32 flags,
uint64 produceSize,
uint64 consumeSize,
- VA produceQVA, VA consumeQVA);
+ void *produceQ, void *consumeQ);
static void QueuePairEntryDestroy(QueuePairEntry *entry);
static int VMCIQueuePairAlloc_HyperCall(const QueuePairEntry *entry);
static int VMCIQueuePairAllocHelper(VMCIHandle *handle, VMCIQueue **produceQ,
uint32 flags, // IN:
uint64 produceSize, // IN:
uint64 consumeSize, // IN:
- VA produceQVA, // IN:
- VA consumeQVA) // IN:
+ void *produceQ, // IN:
+ void *consumeQ) // IN:
{
static VMCIId queuePairRID = VMCI_RESERVED_RESOURCE_ID_MAX + 1;
QueuePairEntry *entry;
CEILING(consumeSize, PAGE_SIZE) +
2; /* One page each for the queue headers. */
- ASSERT((produceSize || consumeSize) && produceQVA && consumeQVA);
+ ASSERT((produceSize || consumeSize) && produceQ && consumeQ);
if (VMCI_HANDLE_INVALID(handle)) {
VMCIId contextID = VMCI_GetContextID();
entry->consumeSize = consumeSize;
entry->numPPNs = numPPNs;
memset(&entry->ppnSet, 0, sizeof entry->ppnSet);
- entry->produceQVA = produceQVA;
- entry->consumeQVA = consumeQVA;
+ entry->produceQ = produceQ;
+ entry->consumeQ = consumeQ;
entry->refCount = 0;
INIT_LIST_ITEM(&entry->listItem);
}
ASSERT(entry->refCount == 0);
VMCI_FreePPNSet(&entry->ppnSet);
- VMCI_FreeQueueKVA(entry->produceQVA, entry->produceSize);
- VMCI_FreeQueueKVA(entry->consumeQVA, entry->consumeSize);
+ VMCI_FreeQueue(entry->produceQ, entry->produceSize);
+ VMCI_FreeQueue(entry->consumeQ, entry->consumeSize);
VMCI_FreeKernelMem(entry, sizeof *entry);
}
{
const uint64 numProducePages = CEILING(produceSize, PAGE_SIZE) + 1;
const uint64 numConsumePages = CEILING(consumeSize, PAGE_SIZE) + 1;
- VA produceVA = 0;
- VA consumeVA = 0;
+ void *myProduceQ = NULL;
+ void *myConsumeQ = NULL;
int result;
QueuePairEntry *queuePairEntry = NULL;
if (result < VMCI_SUCCESS) {
goto errorKeepEntry;
}
- produceVA = queuePairEntry->consumeQVA;
- consumeVA = queuePairEntry->produceQVA;
+ myProduceQ = queuePairEntry->consumeQ;
+ myConsumeQ = queuePairEntry->produceQ;
goto out;
}
result = VMCI_ERROR_ALREADY_EXISTS;
goto errorKeepEntry;
}
- produceVA = VMCI_AllocQueueKVA(produceSize);
- if (!produceVA) {
+ myProduceQ = VMCI_AllocQueue(produceSize);
+ if (!myProduceQ) {
VMCI_LOG((LGPFX "Error allocating pages for produce queue.\n"));
result = VMCI_ERROR_NO_MEM;
goto error;
}
- consumeVA = VMCI_AllocQueueKVA(consumeSize);
- if (!consumeVA) {
+ myConsumeQ = VMCI_AllocQueue(consumeSize);
+ if (!myConsumeQ) {
VMCI_LOG((LGPFX "Error allocating pages for consume queue.\n"));
result = VMCI_ERROR_NO_MEM;
goto error;
queuePairEntry = QueuePairEntryCreate(*handle, peer, flags,
produceSize, consumeSize,
- produceVA, consumeVA);
+ myProduceQ, myConsumeQ);
if (!queuePairEntry) {
VMCI_LOG((LGPFX "Error allocating memory in %s.\n", __FUNCTION__));
result = VMCI_ERROR_NO_MEM;
goto error;
}
- result = VMCI_AllocPPNSet(produceVA, numProducePages, consumeVA,
+ result = VMCI_AllocPPNSet(myProduceQ, numProducePages, myConsumeQ,
numConsumePages, &queuePairEntry->ppnSet);
if (result < VMCI_SUCCESS) {
VMCI_LOG((LGPFX "VMCI_AllocPPNSet failed.\n"));
out:
queuePairEntry->refCount++;
*handle = queuePairEntry->handle;
- *produceQ = (VMCIQueue *)produceVA;
- *consumeQ = (VMCIQueue *)consumeVA;
+ *produceQ = (VMCIQueue *)myProduceQ;
+ *consumeQ = (VMCIQueue *)myConsumeQ;
/*
* We should initialize the queue pair header pages on a local queue pair
error:
QueuePairList_Unlock();
if (queuePairEntry) {
- /* The KVAs will be freed inside the destroy routine. */
+ /* The queues will be freed inside the destroy routine. */
QueuePairEntryDestroy(queuePairEntry);
} else {
- if (produceVA) {
- VMCI_FreeQueueKVA(produceVA, produceSize);
+ if (myProduceQ) {
+ VMCI_FreeQueue(myProduceQ, produceSize);
}
- if (consumeVA) {
- VMCI_FreeQueueKVA(consumeVA, consumeSize);
+ if (myConsumeQ) {
+ VMCI_FreeQueue(myConsumeQ, consumeSize);
}
}
return result;
break;
}
ASSERT(!devHndl->obj);
- retval = VMCIProcess_Create((VMCIProcess **) &devHndl->obj, -1);
+ retval = VMCIProcess_Create((VMCIProcess **) &devHndl->obj);
if (retval != 0) {
printk("VMCI: Failed to create process.\n");
break;
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmci_kernel_if.h --
- *
- * This file defines helper functions for VMCI host _and_ guest
- * kernel code. It must work for windows, macosx, vmkernel and
- * linux kernel, ie. using defines where necessary.
- */
-
-#ifndef _VMCI_KERNEL_IF_H_
-#define _VMCI_KERNEL_IF_H_
-
-#if !defined(linux) && !defined(_WIN32) && !defined(__APPLE__) && \
- !defined(VMKERNEL) && !defined(SOLARIS)
-#error "Platform not supported."
-#endif
-
-#if defined(_WIN32)
-#include <ntddk.h>
-#endif
-
-#if defined(linux) && !defined(VMKERNEL)
-# include "compat_version.h"
-# include "compat_wait.h"
-# include "compat_spinlock.h"
-# include "compat_semaphore.h"
-#endif // linux
-
-#ifdef __APPLE__
-# include <IOKit/IOLib.h>
-#include <mach/task.h>
-#include <mach/semaphore.h>
-#endif
-
-#ifdef VMKERNEL
-#include "splock.h"
-#include "semaphore_ext.h"
-#endif
-
-#ifdef SOLARIS
-# include <sys/mutex.h>
-# include <sys/poll.h>
-# include <sys/semaphore.h>
-# include <sys/kmem.h>
-#endif
-
-#include "vm_basic_types.h"
-#include "vmci_defs.h"
-
-/* Flags for specifying memory type. */
-#define VMCI_MEMORY_NORMAL 0x0
-#define VMCI_MEMORY_ATOMIC 0x1
-#define VMCI_MEMORY_NONPAGED 0x2
-
-/* Platform specific type definitions. */
-
-#if defined(VMKERNEL)
- typedef SP_SpinLock VMCILock;
- typedef SP_IRQL VMCILockFlags;
- typedef Semaphore VMCIEvent;
- typedef Semaphore VMCIMutex;
-#elif defined(linux)
- typedef spinlock_t VMCILock;
- typedef unsigned long VMCILockFlags;
- typedef wait_queue_head_t VMCIEvent;
- typedef struct semaphore VMCIMutex;
- typedef PPN *VMCIPpnList; /* List of PPNs in produce/consume queue. */
-#elif defined(__APPLE__)
- typedef IOLock *VMCILock;
- typedef unsigned long VMCILockFlags;
- typedef semaphore_t VMCIEvent;
- typedef IOLock *VMCIMutex;
- typedef void *VMCIPpnList; /* Actually a pointer to the C++ Object IOMemoryDescriptor */
-#elif defined(_WIN32)
- typedef KSPIN_LOCK VMCILock;
- typedef KIRQL VMCILockFlags;
- typedef KEVENT VMCIEvent;
- typedef FAST_MUTEX VMCIMutex;
- typedef PMDL VMCIPpnList; /* MDL to map the produce/consume queue. */
-#elif defined(SOLARIS)
- typedef kmutex_t VMCILock;
- typedef unsigned long VMCILockFlags;
- typedef ksema_t VMCIEvent;
- typedef kmutex_t VMCIMutex;
- typedef PPN *VMCIPpnList; /* List of PPNs in produce/consume queue. */
-#endif // VMKERNEL
-
-/* Callback needed for correctly waiting on events. */
-typedef int (*VMCIEventReleaseCB)(void *clientData);
-
-/*
- * The VMCI locks use a ranking scheme similar to the one used by
- * vmkernel. While holding a lock L1 with rank R1, only locks with
- * rank higher than R1 may be grabbed. The available ranks for VMCI
- * locks are (in descending order):
- * - VMCI_LOCK_RANK_HIGH_BH : to be used for locks grabbed while executing
- * in a bottom half and not held while grabbing other locks.
- * - VMCI_LOCK_RANK_MIDDLE_BH : to be for locks grabbed while executing in a
- * bottom half and held while grabbing locks of rank VMCI_LOCK_RANK_HIGH_BH.
- * - VMCI_LOCK_RANK_LOW_BH : to be for locks grabbed while executing in a
- * bottom half and held while grabbing locks of rank
- * VMCI_LOCK_RANK_MIDDLE_BH.
- * - VMCI_LOCK_RANK_HIGHEST : to be used for locks that are not held while
- * grabbing other locks except system locks with higher ranks and bottom
- * half locks.
- * - VMCI_LOCK_RANK_HIGHER : to be used for locks that are held while
- * grabbing locks of rank VMCI_LOCK_RANK_HIGHEST or higher.
- * - VMCI_LOCK_RANK_HIGH : to be used for locks that are held while
- * grabbing locks of rank VMCI_LOCK_RANK_HIGHER or higher. This is
- * the highest lock rank used by core VMCI services
- * - VMCI_LOCK_RANK_MIDDLE : to be used for locks that are held while
- * grabbing locks of rank VMCI_LOCK_RANK_HIGH or higher.
- * - VMCI_LOCK_RANK_LOW : to be used for locks that are held while
- * grabbing locks of rank VMCI_LOCK_RANK_MIDDLE or higher.
- * - VMCI_LOCK_RANK_LOWEST : to be used for locks that are held while
- * grabbing locks of rank VMCI_LOCK_RANK_LOW or higher.
- */
-#ifdef VMKERNEL
- typedef SP_Rank VMCILockRank;
-
- #define VMCI_LOCK_RANK_HIGH_BH SP_RANK_IRQ_LEAF
- #define VMCI_LOCK_RANK_MIDDLE_BH (SP_RANK_IRQ_LEAF-1)
- #define VMCI_LOCK_RANK_LOW_BH SP_RANK_IRQ_LOWEST
- #define VMCI_LOCK_RANK_HIGHEST SP_RANK_SHM_MGR-1
-#else
- typedef unsigned long VMCILockRank;
-
- #define VMCI_LOCK_RANK_HIGH_BH 0x4000
- #define VMCI_LOCK_RANK_MIDDLE_BH 0x2000
- #define VMCI_LOCK_RANK_LOW_BH 0x1000
- #define VMCI_LOCK_RANK_HIGHEST 0x0fff
-#endif // VMKERNEL
-#define VMCI_LOCK_RANK_HIGHER (VMCI_LOCK_RANK_HIGHEST-1)
-#define VMCI_LOCK_RANK_HIGH (VMCI_LOCK_RANK_HIGHER-1)
-#define VMCI_LOCK_RANK_MIDDLE_HIGH (VMCI_LOCK_RANK_HIGH-1)
-#define VMCI_LOCK_RANK_MIDDLE (VMCI_LOCK_RANK_MIDDLE_HIGH-1)
-#define VMCI_LOCK_RANK_MIDDLE_LOW (VMCI_LOCK_RANK_MIDDLE-1)
-#define VMCI_LOCK_RANK_LOW (VMCI_LOCK_RANK_MIDDLE_LOW-1)
-#define VMCI_LOCK_RANK_LOWEST (VMCI_LOCK_RANK_LOW-1)
-
-
-/*
- * In vmkernel, we try to reduce the amount of memory mapped into the
- * virtual address space by only mapping the memory of buffered
- * datagrams when copying from and to the guest. In other OSes,
- * regular kernel memory is used. VMCIBuffer is used to reference
- * possibly unmapped memory.
- */
-
-#ifdef VMKERNEL
-typedef MPN VMCIBuffer;
-#define VMCI_BUFFER_INVALID INVALID_MPN
-#else
-typedef void * VMCIBuffer;
-#define VMCI_BUFFER_INVALID NULL
-#endif
-
-/*
- * Host specific struct used for signalling.
- */
-
-typedef struct VMCIHost {
-#if defined(VMKERNEL)
- World_ID vmmWorldID;
-#elif defined(linux)
- wait_queue_head_t waitQueue;
-#elif defined(__APPLE__)
- struct Socket *socket; /* vmci Socket object on Mac OS. */
-#elif defined(_WIN32)
- KEVENT *callEvent; /* Ptr to userlevel event used when signalling
- * new pending guestcalls in kernel.
- */
-#elif defined(SOLARIS)
- struct pollhead pollhead; /* Per datagram handle pollhead structure to
- * be treated as a black-box. None of its
- * fields should be referenced.
- */
-#endif
-} VMCIHost;
-
-
-void VMCI_InitLock(VMCILock *lock, char *name, VMCILockRank rank);
-void VMCI_CleanupLock(VMCILock *lock);
-void VMCI_GrabLock(VMCILock *lock, VMCILockFlags *flags);
-void VMCI_ReleaseLock(VMCILock *lock, VMCILockFlags flags);
-void VMCI_GrabLock_BH(VMCILock *lock, VMCILockFlags *flags);
-void VMCI_ReleaseLock_BH(VMCILock *lock, VMCILockFlags flags);
-
-void VMCIHost_InitContext(VMCIHost *hostContext, uintptr_t eventHnd);
-void VMCIHost_ReleaseContext(VMCIHost *hostContext);
-void VMCIHost_SignalCall(VMCIHost *hostContext);
-void VMCIHost_ClearCall(VMCIHost *hostContext);
-Bool VMCIHost_WaitForCallLocked(VMCIHost *hostContext,
- VMCILock *lock,
- VMCILockFlags *flags,
- Bool useBH);
-
-void *VMCI_AllocKernelMem(size_t size, int flags);
-void VMCI_FreeKernelMem(void *ptr, size_t size);
-VMCIBuffer VMCI_AllocBuffer(size_t size, int flags);
-void *VMCI_MapBuffer(VMCIBuffer buf);
-void VMCI_ReleaseBuffer(void *ptr);
-void VMCI_FreeBuffer(VMCIBuffer buf, size_t size);
-#ifdef SOLARIS
-int VMCI_CopyToUser(void *dst, const void *src, unsigned int len, int mode);
-#else
-int VMCI_CopyToUser(void *dst, const void *src, unsigned int len);
-/*
- * Don't need the following for guests, hence no Solaris code for this
- * function.
- */
-Bool VMCIWellKnownID_AllowMap(VMCIId wellKnownID,
- VMCIPrivilegeFlags privFlags);
-#endif
-
-void VMCI_CreateEvent(VMCIEvent *event);
-void VMCI_DestroyEvent(VMCIEvent *event);
-void VMCI_SignalEvent(VMCIEvent *event);
-void VMCI_WaitOnEvent(VMCIEvent *event, VMCIEventReleaseCB releaseCB,
- void *clientData);
-#if (defined(__linux__) || defined(_WIN32)) && !defined(VMKERNEL)
-Bool VMCI_WaitOnEventInterruptible(VMCIEvent *event,
- VMCIEventReleaseCB releaseCB,
- void *clientData);
-#endif
-
-#if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \
- defined(__APPLE__) || defined(SOLARIS))
-int VMCI_CopyFromUser(void *dst, const void *src, size_t len);
-#endif
-
-int VMCIMutex_Init(VMCIMutex *mutex);
-void VMCIMutex_Destroy(VMCIMutex *mutex);
-void VMCIMutex_Acquire(VMCIMutex *mutex);
-void VMCIMutex_Release(VMCIMutex *mutex);
-
-#if defined(SOLARIS)
-int VMCIKernelIf_Init(void);
-void VMCIKernelIf_Exit(void);
-#endif /* SOLARIS */
-
-#if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \
- defined(SOLARIS) || defined(__APPLE__))
-VA VMCI_AllocQueueKVA(uint64 size);
-void VMCI_FreeQueueKVA(VA va, uint64 size);
-typedef struct PPNSet {
- uint64 numProducePages;
- uint64 numConsumePages;
- VMCIPpnList producePPNs;
- VMCIPpnList consumePPNs;
- Bool initialized;
-} PPNSet;
-int VMCI_AllocPPNSet(VA produceVA, uint64 numProducePages, VA consumeVA,
- uint64 numConsumePages, PPNSet *ppnSet);
-void VMCI_FreePPNSet(PPNSet *ppnSet);
-int VMCI_PopulatePPNList(uint8 *callBuf, const PPNSet *ppnSet);
-#endif
-
-#if (defined(_WIN32) || defined(__linux__)) && !defined(VMKERNEL) && \
- !defined(VMX86_TOOLS)
-struct PageStoreAttachInfo;
-struct VMCIQueue;
-
-int VMCIHost_GetUserMemory(struct PageStoreAttachInfo *attach);
-void VMCIHost_ReleaseUserMemory(struct PageStoreAttachInfo *attach);
-int VMCIHost_FinishAttach(struct PageStoreAttachInfo *attach,
- struct VMCIQueue *produceQ,
- struct VMCIQueue *detachQ);
-void VMCIHost_DetachMappings(struct PageStoreAttachInfo *attach);
-#endif
-
-#endif // _VMCI_KERNEL_IF_H_
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware.h --
- *
- * Standard include file for VMware source code.
- */
-
-#ifndef _VMWARE_H_
-#define _VMWARE_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-#include "vm_basic_defs.h"
-#include "vm_assert.h"
-
-/*
- * Global error codes. Currently used internally, but may be exported
- * to customers one day, like VM_E_XXX in vmcontrol_constants.h
- */
-
-typedef enum VMwareStatus {
- VMWARE_STATUS_SUCCESS, /* success */
- VMWARE_STATUS_ERROR, /* generic error */
- VMWARE_STATUS_NOMEM, /* generic memory allocation error */
- VMWARE_STATUS_INSUFFICIENT_RESOURCES, /* internal or system resource limit exceeded */
- VMWARE_STATUS_INVALID_ARGS /* invalid arguments */
-} VMwareStatus;
-
-#define VMWARE_SUCCESS(s) ((s) == VMWARE_STATUS_SUCCESS)
-
-
-#endif // ifndef _VMWARE_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_begin.h --
- *
- * Begin of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(push, 1)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_end.h --
- *
- * End of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(pop)
-#elif __GNUC__
-__attribute__((__packed__))
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __VMWARE_PACK_INIT_H__
-# define __VMWARE_PACK_INIT_H__
-
-
-/*
- * vmware_pack_init.h --
- *
- * Platform-independent code to make the compiler pack (i.e. have them
- * occupy the smallest possible space) structure definitions. The following
- * constructs are known to work --hpreg
- *
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * ;
- *
- * typedef
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * foo;
- */
-
-
-#ifdef _MSC_VER
-/*
- * MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is
- * not balanced within 1 included file. That is annoying because our scheme
- * is based on the pairing being balanced between 2 included files.
- *
- * So we disable this warning, but this is safe because the compiler will also
- * emit warning 4161 when there is more pops than pushes within 1 main
- * file --hpreg
- */
-
-# pragma warning(disable:4103)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
-
-
-#endif /* __VMWARE_PACK_INIT_H__ */
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmhgfs
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#### VMware vmhgfs Makefile to be distributed externally
####
-INCLUDE := -I.
+INCLUDE += -I.
+
+ifdef OVT_SOURCE_DIR
+INCLUDE += -I$(call VMLIB_PATH,backdoor)
+INCLUDE += -I$(call VMLIB_PATH,hgfs)
+endif
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/maxbytes.c, -DVMW_SB_HAS_MAXBYTES, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/maxbytes.c, -DVMW_SB_HAS_MAXBYTES, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, )
# Note: These tests are inverted
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/getsb1.c,, -DVMW_GETSB_2618)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/statfs1.c,, -DVMW_STATFS_2618)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/inode1.c,, -DVMW_INODE_2618)
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/getsb1.c,, -DVMW_GETSB_2618)
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/statfs1.c,, -DVMW_STATFS_2618)
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/inode1.c,, -DVMW_INODE_2618)
obj-m += $(DRIVER).o
CC_OPTS := -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS)
-INCLUDE := -I. -I$(HEADER_DIR)
+INCLUDE += -I. -I$(HEADER_DIR)
-INCLUDE += $(shell $(CC) $(INCLUDE) -E $(SRCROOT)/autoconf/geninclude.c \
+INCLUDE += $(shell $(CC) $(INCLUDE) -E $(AUTOCONF_DIR)/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/maxbytes.c, -DVMW_SB_HAS_MAXBYTES, )
+ifdef OVT_SOURCE_DIR
+INCLUDE += -I$(call VMLIB_PATH,backdoor)
+INCLUDE += -I$(call VMLIB_PATH,hgfs)
+endif
+
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/maxbytes.c, -DVMW_SB_HAS_MAXBYTES, )
CC_OPTS += -DVMW_KMEMCR_HAS_DTOR
# Core driver components
OBJS += request.o
OBJS += stubs.o
OBJS += super.o
+OBJS += tcp.o
+OBJS += transport.o
# Additional components
OBJS += backdoor.o
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * All kernels before 2.6.22 take 6 arguments. All kernels since
- * 2.6.23-rc1 take 5 arguments. Only kernels between 2.6.22 and
- * 2.6.23-rc1 are questionable - we could ignore them if we wanted,
- * nobody cares about them even now. But unfortunately RedHat is
- * re-releasing 2.6.X-rc kernels under 2.6.(X-1) name, so they
- * are releasing 2.6.23-rc1 as 2.6.22-5055-something, so we have
- * to do autodetection for them.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
-/* Success... */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#error "This test intentionally fails on 2.6.23 and newer kernels."
-#else
-#include <linux/slab.h>
-
-struct kmem_cache *kmemtest(void) {
- return kmem_cache_create("test", 12, 0, 0, NULL, NULL);
-}
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * Between 2.6.23 and 2.6.24-rc1 ctor prototype was changed from
- * ctor(ptr, cache, flags) to ctor(cache, ptr). Unfortunately there
- * is no typedef for ctor, so we have to redefine kmem_cache_create
- * to find out ctor prototype. This assumes that kmem_cache_create
- * takes 5 arguments and not 6 - that change occured between
- * 2.6.22 and 2.6.23-rc1. If prototype matches, then this is old
- * kernel.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-#error "This test intentionally fails on 2.6.24 and newer kernels."
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#include <linux/slab.h>
-
-struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
- unsigned long,
- void (*)(void *, struct kmem_cache *, unsigned long));
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * Between 2.6.27-rc1 and 2.6.27-rc2 ctor prototype was changed from
- * ctor(cache, ptr) to ctor(ptr). Unfortunately there
- * is no typedef for ctor, so we have to redefine kmem_cache_create
- * to find out ctor prototype. If prototype matches, then this is old
- * kernel.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-#error "This test intentionally fails on 2.6.28 and newer kernels."
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
-#include <linux/slab.h>
-
-struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
- unsigned long,
- void (*)(struct kmem_cache *, void *));
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Detect whether we have 'struct poll_wqueues'
- * 2.6.x kernels always had this struct. Stock 2.4.x kernels
- * never had it, but some distros backported epoll patch.
- */
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-#include <linux/poll.h>
-
-void poll_test(void) {
- struct poll_wqueues test;
-
- return poll_initwait(&test);
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-
-#ifdef CONFIG_X86_VOYAGER
-APATH/mach-voyager
-#endif
-#ifdef CONFIG_X86_VISWS
-APATH/mach-visws
-#endif
-#ifdef CONFIG_X86_NUMAQ
-APATH/mach-numaq
-#endif
-#ifdef CONFIG_X86_BIGSMP
-APATH/mach-bigsmp
-#endif
-#ifdef CONFIG_X86_SUMMIT
-APATH/mach-summit
-#endif
-#ifdef CONFIG_X86_GENERICARCH
-APATH/mach-generic
-#endif
-APATH/mach-default
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-
-#include <linux/fs.h>
-
-/*
- * Around 2.6.18, a pointer to a vfsmount was added to get_sb. Red Hat
- * backported this behavior into a 2.6.17 kernel.
- *
- * This test will fail on a kernel with such a patch.
- */
-static struct super_block * LinuxDriverGetSb(struct file_system_type *fs_type,
- int flags,
- const char *dev_name,
- void *rawData)
-{
- return 0;
-}
-
-struct file_system_type fs_type = {
- .get_sb = LinuxDriverGetSb
-};
-#else
-#error "This test intentionally fails on 2.6.19 or newer kernels."
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * set_user_nice appeared in 2.4.21. But some distros
- * backported it to older kernels.
- */
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 21)
-#include <linux/sched.h>
-
-void test(void) {
- set_user_nice(current, -20);
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include <linux/fs.h>
-
-/*
- * Around 2.6.18, the super_block pointer in statfs was changed to a dentry
- * pointer. Red Hat backported this behavior into a 2.6.17 kernel.
- *
- * This test will fail on a kernel with such a patch.
- */
-static int LinuxDriverStatFs(struct super_block *sb,
- struct kstatfs *stat)
-{
- return 0;
-}
-
-struct super_operations super_ops = {
- .statfs = LinuxDriverStatFs
-};
-#else
-#error "This test intentionally fails on 2.6.19 and newer kernels."
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * backdoor.h --
- *
- * First layer of the internal communication channel between guest
- * applications and vmware
- */
-
-#ifndef _BACKDOOR_H_
-#define _BACKDOOR_H_
-
-#include "vm_basic_types.h"
-#include "vm_assert.h"
-
-#include "backdoor_types.h"
-
-void
-Backdoor(Backdoor_proto *bp); // IN/OUT
-
-void
-Backdoor_InOut(Backdoor_proto *bp); // IN/OUT
-
-void
-Backdoor_HbOut(Backdoor_proto_hb *bp); // IN/OUT
-
-void
-Backdoor_HbIn(Backdoor_proto_hb *bp); // IN/OUT
-
-#endif /* _BACKDOOR_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * backdoor_def.h --
- *
- * This contains backdoor defines that can be included from
- * an assembly language file.
- */
-
-
-
-#ifndef _BACKDOOR_DEF_H_
-#define _BACKDOOR_DEF_H_
-
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMKERNEL
-#include "includeCheck.h"
-
-/*
- * If you want to add a new low-level backdoor call for a guest userland
- * application, please consider using the GuestRpc mechanism instead. --hpreg
- */
-
-#define BDOOR_MAGIC 0x564D5868
-
-/* Low-bandwidth backdoor port. --hpreg */
-
-#define BDOOR_PORT 0x5658
-
-#define BDOOR_CMD_GETMHZ 1
-/*
- * BDOOR_CMD_APMFUNCTION is used by:
- *
- * o The FrobOS code, which instead should either program the virtual chipset
- * (like the new BIOS code does, matthias offered to implement that), or not
- * use any VM-specific code (which requires that we correctly implement
- * "power off on CLI HLT" for SMP VMs, boris offered to implement that)
- *
- * o The old BIOS code, which will soon be jettisoned
- *
- * --hpreg
- */
-#define BDOOR_CMD_APMFUNCTION 2
-#define BDOOR_CMD_GETDISKGEO 3
-#define BDOOR_CMD_GETPTRLOCATION 4
-#define BDOOR_CMD_SETPTRLOCATION 5
-#define BDOOR_CMD_GETSELLENGTH 6
-#define BDOOR_CMD_GETNEXTPIECE 7
-#define BDOOR_CMD_SETSELLENGTH 8
-#define BDOOR_CMD_SETNEXTPIECE 9
-#define BDOOR_CMD_GETVERSION 10
-#define BDOOR_CMD_GETDEVICELISTELEMENT 11
-#define BDOOR_CMD_TOGGLEDEVICE 12
-#define BDOOR_CMD_GETGUIOPTIONS 13
-#define BDOOR_CMD_SETGUIOPTIONS 14
-#define BDOOR_CMD_GETSCREENSIZE 15
-#define BDOOR_CMD_MONITOR_CONTROL 16
-#define BDOOR_CMD_GETHWVERSION 17
-#define BDOOR_CMD_OSNOTFOUND 18
-#define BDOOR_CMD_GETUUID 19
-#define BDOOR_CMD_GETMEMSIZE 20
-#define BDOOR_CMD_HOSTCOPY 21 /* Devel only */
-#define BDOOR_CMD_SERVICE_VM 22 /* prototype only */
-#define BDOOR_CMD_GETTIME 23 /* Deprecated. Use GETTIMEFULL. */
-#define BDOOR_CMD_STOPCATCHUP 24
-#define BDOOR_CMD_PUTCHR 25 /* Devel only */
-#define BDOOR_CMD_ENABLE_MSG 26 /* Devel only */
-#define BDOOR_CMD_GOTO_TCL 27 /* Devel only */
-#define BDOOR_CMD_INITPCIOPROM 28
-#define BDOOR_CMD_INT13 29
-#define BDOOR_CMD_MESSAGE 30
-#define BDOOR_CMD_RSVD0 31
-#define BDOOR_CMD_RSVD1 32
-#define BDOOR_CMD_RSVD2 33
-#define BDOOR_CMD_ISACPIDISABLED 34
-#define BDOOR_CMD_TOE 35 /* Not in use */
-#define BDOOR_CMD_ISMOUSEABSOLUTE 36
-#define BDOOR_CMD_PATCH_SMBIOS_STRUCTS 37
-#define BDOOR_CMD_MAPMEM 38 /* Devel only */
-#define BDOOR_CMD_ABSPOINTER_DATA 39
-#define BDOOR_CMD_ABSPOINTER_STATUS 40
-#define BDOOR_CMD_ABSPOINTER_COMMAND 41
-#define BDOOR_CMD_TIMER_SPONGE 42
-#define BDOOR_CMD_PATCH_ACPI_TABLES 43
-/* Catch-all to allow synchronous tests */
-#define BDOOR_CMD_DEVEL_FAKEHARDWARE 44 /* Debug only - needed in beta */
-#define BDOOR_CMD_GETHZ 45
-#define BDOOR_CMD_GETTIMEFULL 46
-#define BDOOR_CMD_STATELOGGER 47
-#define BDOOR_CMD_CHECKFORCEBIOSSETUP 48
-#define BDOOR_CMD_LAZYTIMEREMULATION 49
-#define BDOOR_CMD_BIOSBBS 50
-#define BDOOR_CMD_VASSERT 51
-#define BDOOR_CMD_ISGOSDARWIN 52
-#define BDOOR_CMD_DEBUGEVENT 53
-#define BDOOR_CMD_OSNOTMACOSXSERVER 54
-#define BDOOR_CMD_GETTIMEFULL_WITH_LAG 55
-#define BDOOR_CMD_ACPI_HOTPLUG_DEVICE 56
-#define BDOOR_CMD_ACPI_HOTPLUG_MEMORY 57
-#define BDOOR_CMD_ACPI_HOTPLUG_CBRET 58
-#define BDOOR_CMD_GET_HOST_VIDEO_MODES 59
-#define BDOOR_CMD_ACPI_HOTPLUG_CPU 60
-#define BDOOR_CMD_MAX 61
-
-/*
- * IMPORTANT NOTE: When modifying the behavior of an existing backdoor command,
- * you must adhere to the semantics expected by the oldest Tools who use that
- * command. Specifically, do not alter the way in which the command modifies
- * the registers. Otherwise backwards compatibility will suffer.
- */
-
-/* High-bandwidth backdoor port. --hpreg */
-
-#define BDOORHB_PORT 0x5659
-
-#define BDOORHB_CMD_MESSAGE 0
-#define BDOORHB_CMD_VASSERT 1
-#define BDOORHB_CMD_MAX 2
-
-/*
- * There is another backdoor which allows access to certain TSC-related
- * values using otherwise illegal PMC indices when the pseudo_perfctr
- * control flag is set.
- */
-
-#define BDOOR_PMC_HW_TSC 0x10000
-#define BDOOR_PMC_REAL_NS 0x10001
-#define BDOOR_PMC_APPARENT_NS 0x10002
-
-#define IS_BDOOR_PMC(index) (((index) | 3) == 0x10003)
-#define BDOOR_CMD(ecx) ((ecx) & 0xffff)
-
-
-#ifdef VMM
-/*
- *----------------------------------------------------------------------
- *
- * Backdoor_CmdRequiresFullyValidVCPU --
- *
- * A few backdoor commands require the full VCPU to be valid
- * (including GDTR, IDTR, TR and LDTR). The rest get read/write
- * access to GPRs and read access to Segment registers (selectors).
- *
- * Result:
- * True iff VECX contains a command that require the full VCPU to
- * be valid.
- *
- *----------------------------------------------------------------------
- */
-static INLINE Bool
-Backdoor_CmdRequiresFullyValidVCPU(unsigned cmd)
-{
- return cmd == BDOOR_CMD_RSVD0 ||
- cmd == BDOOR_CMD_RSVD1 ||
- cmd == BDOOR_CMD_RSVD2;
-}
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * backdoor_types.h --
- *
- * Type definitions for backdoor interaction code.
- */
-
-#ifndef _BACKDOOR_TYPES_H_
-#define _BACKDOOR_TYPES_H_
-
-#ifndef VM_I386
-#error The backdoor protocol is only supported on x86 architectures.
-#endif
-
-/*
- * These #defines are intended for defining register structs as part of
- * existing named unions. If the union should encapsulate the register
- * (and nothing else), use DECLARE_REG_NAMED_STRUCT defined below.
- */
-
-#define DECLARE_REG32_STRUCT \
- struct { \
- uint16 low; \
- uint16 high; \
- } halfs; \
- uint32 word
-
-#define DECLARE_REG64_STRUCT \
- DECLARE_REG32_STRUCT; \
- struct { \
- uint32 low; \
- uint32 high; \
- } words; \
- uint64 quad
-
-#ifndef VM_X86_64
-#define DECLARE_REG_STRUCT DECLARE_REG32_STRUCT
-#else
-#define DECLARE_REG_STRUCT DECLARE_REG64_STRUCT
-#endif
-
-#define DECLARE_REG_NAMED_STRUCT(_r) \
- union { DECLARE_REG_STRUCT; } _r
-
-/*
- * Some of the registers are expressed by semantic name, because if they were
- * expressed as register structs declared above, we could only address them
- * by fixed size (half-word, word, quad, etc.) instead of by varying size
- * (size_t, uintptr_t).
- *
- * To be cleaner, these registers are expressed ONLY by semantic name,
- * rather than by a union of the semantic name and a register struct.
- */
-typedef union {
- struct {
- DECLARE_REG_NAMED_STRUCT(ax);
- size_t size; /* Register bx. */
- DECLARE_REG_NAMED_STRUCT(cx);
- DECLARE_REG_NAMED_STRUCT(dx);
- DECLARE_REG_NAMED_STRUCT(si);
- DECLARE_REG_NAMED_STRUCT(di);
- } in;
- struct {
- DECLARE_REG_NAMED_STRUCT(ax);
- DECLARE_REG_NAMED_STRUCT(bx);
- DECLARE_REG_NAMED_STRUCT(cx);
- DECLARE_REG_NAMED_STRUCT(dx);
- DECLARE_REG_NAMED_STRUCT(si);
- DECLARE_REG_NAMED_STRUCT(di);
- } out;
-} Backdoor_proto;
-
-typedef union {
- struct {
- DECLARE_REG_NAMED_STRUCT(ax);
- DECLARE_REG_NAMED_STRUCT(bx);
- size_t size; /* Register cx. */
- DECLARE_REG_NAMED_STRUCT(dx);
- uintptr_t srcAddr; /* Register si. */
- uintptr_t dstAddr; /* Register di. */
- DECLARE_REG_NAMED_STRUCT(bp);
- } in;
- struct {
- DECLARE_REG_NAMED_STRUCT(ax);
- DECLARE_REG_NAMED_STRUCT(bx);
- DECLARE_REG_NAMED_STRUCT(cx);
- DECLARE_REG_NAMED_STRUCT(dx);
- DECLARE_REG_NAMED_STRUCT(si);
- DECLARE_REG_NAMED_STRUCT(di);
- DECLARE_REG_NAMED_STRUCT(bp);
- } out;
-} Backdoor_proto_hb;
-
-MY_ASSERTS(BACKDOOR_STRUCT_SIZES,
- ASSERT_ON_COMPILE(sizeof(Backdoor_proto) == 6 * sizeof(uintptr_t));
- ASSERT_ON_COMPILE(sizeof(Backdoor_proto_hb) == 7 * sizeof(uintptr_t));
-)
-
-#undef DECLARE_REG_STRUCT
-
-#endif /* _BACKDOOR_TYPES_H_ */
/* Must come before any kernel header file. */
#include "driver-config.h"
-#include <asm/atomic.h>
#include <linux/errno.h>
-#include "compat_completion.h"
-#include "compat_kernel.h"
-#include "compat_kthread.h"
-#include "compat_list.h"
-#include "compat_sched.h"
-#include "compat_semaphore.h"
-#include "compat_slab.h"
-#include "compat_spinlock.h"
-#include "compat_version.h"
-
-/* Must be included after semaphore.h. */
-#include <linux/timer.h>
-/* Must be included after sched.h. */
-#include <linux/smp_lock.h>
+#include "bdhandler.h"
#include "hgfsBd.h"
#include "hgfsDevLinux.h"
#include "hgfsProto.h"
-#include "bdhandler.h"
#include "module.h"
#include "request.h"
-#include "vm_assert.h"
#include "rpcout.h"
+#include "transport.h"
+#include "vm_assert.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)
-int errno; /* compat_exit() needs global errno variable. */
-#endif
-
-static inline void HgfsWakeWaitingClient(HgfsReq *req);
-static inline void HgfsCompleteReq(HgfsReq *req,
- char const *reply,
- size_t replySize);
-static void HgfsSendUnsentReqs(void);
+HgfsTransportChannel bdChannel;
-/*
- * Private function implementations.
- */
/*
- *----------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
*
- * HgfsWakeWaitingClient --
+ * HgfsBdChannelOpen --
*
- * Wakes up the client process waiting for the reply to this
- * request.
+ * Open the backdoor in an idempotent way.
*
* Results:
- * None
+ * TRUE on success, FALSE on failure.
*
* Side effects:
- * None
+ * None
*
- *----------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
*/
-static inline void
-HgfsWakeWaitingClient(HgfsReq *req) // IN: Request
+static Bool
+HgfsBdChannelOpen(void)
{
- ASSERT(req);
- wake_up(&req->queue);
+ Bool ret = FALSE;
+
+ compat_mutex_lock(&bdChannel.connLock);
+ switch (bdChannel.status) {
+ case HGFS_CHANNEL_UNINITIALIZED:
+ ret = FALSE;
+ break;
+ case HGFS_CHANNEL_CONNECTED:
+ ret = TRUE;
+ break;
+ case HGFS_CHANNEL_DISCONNECTED:
+ if (HgfsBd_OpenBackdoor((RpcOut **)&bdChannel.priv)) {
+ LOG(8, ("VMware hgfs: %s: backdoor opened.\n", __FUNCTION__));
+ bdChannel.status = HGFS_CHANNEL_CONNECTED;
+ ret = TRUE;
+ ASSERT(bdChannel.priv != NULL);
+ } else {
+ ret = FALSE;
+ }
+ break;
+ default:
+ ASSERT(0); /* Not reached. */
+ }
+
+ compat_mutex_unlock(&bdChannel.connLock);
+ return ret;
}
/*
- *----------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
*
- * HgfsCompleteReq --
+ * HgfsBdChannelClose --
*
- * Copies the reply packet into the request structure and wakes up
- * the associated client.
+ * Close the backdoor in an idempotent way.
*
* Results:
- * None
+ * None
*
* Side effects:
- * None
+ * None
*
- *----------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
*/
-static inline void
-HgfsCompleteReq(HgfsReq *req, // IN: Request
- char const *reply, // IN: Reply packet
- size_t replySize) // IN: Size of reply packet
+static void
+HgfsBdChannelClose(void)
{
- ASSERT(replySize <= HGFS_PACKET_MAX);
-
- memcpy(HGFS_REQ_PAYLOAD(req), reply, replySize);
- req->payloadSize = replySize;
- req->state = HGFS_REQ_STATE_COMPLETED;
- list_del_init(&req->list);
- HgfsWakeWaitingClient(req);
+ compat_mutex_lock(&bdChannel.connLock);
+ if (bdChannel.status == HGFS_CHANNEL_CONNECTED) {
+ ASSERT(bdChannel.priv != NULL);
+ HgfsBd_CloseBackdoor((RpcOut **)&bdChannel.priv);
+ ASSERT(bdChannel.priv == NULL);
+ bdChannel.status = HGFS_CHANNEL_DISCONNECTED;
+ }
+ compat_mutex_unlock(&bdChannel.connLock);
+ LOG(8, ("VMware hgfs: %s: backdoor closed.\n", __FUNCTION__));
}
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
- * HgfsSendUnsentReqs --
+ * HgfsBdChannelSend --
*
- * Process the unsent list and send requests to the backdoor.
+ * Send a request via backdoor.
*
* Results:
- * None.
+ * 0 on success, negative error on failure.
*
* Side effects:
- * None.
+ * None
*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
-static void
-HgfsSendUnsentReqs(void)
+static int
+HgfsBdChannelSend(HgfsReq *req) // IN: request to send
{
- char const *replyPacket;
- struct list_head *cur, *tmp;
- HgfsReq *req;
+ char const *replyPacket = NULL;
size_t payloadSize;
+ int ret;
- spin_lock(&hgfsBigLock);
- list_for_each_safe(cur, tmp, &hgfsReqsUnsent) {
- req = list_entry(cur, HgfsReq, list);
-
- /*
- * A big "wtf" from the driver is in order. Perhaps by "wtf" I really
- * mean BUG_ON().
- */
- ASSERT(req->state == HGFS_REQ_STATE_UNSENT);
- if (req->state != HGFS_REQ_STATE_UNSENT) {
- LOG(2, (KERN_DEBUG "VMware hgfs: HgfsSendUnsentReqs: Found request "
- "on unsent list in the wrong state, ignoring\n"));
- continue;
- }
-
- ASSERT(req->payloadSize <= HGFS_PACKET_MAX);
- payloadSize = req->payloadSize;
- LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendUnsentReqs: Sending packet "
- "over backdoor\n"));
-
- /*
- * We should attempt to reopen the backdoor channel with every request,
- * because the HGFS server in the host can be enabled or disabled at any
- * time.
- */
- if (!HgfsBd_OpenBackdoor(&hgfsRpcOut)) {
- req->state = HGFS_REQ_STATE_ERROR;
- list_del_init(&req->list);
- printk(KERN_WARNING "VMware hgfs: HGFS is disabled in the host\n");
- HgfsWakeWaitingClient(req);
- } else if (HgfsBd_Dispatch(hgfsRpcOut, HGFS_REQ_PAYLOAD(req),
- &payloadSize, &replyPacket) == 0) {
+ ASSERT(req);
+ ASSERT(req->state == HGFS_REQ_STATE_UNSENT);
+ ASSERT(req->payloadSize <= HGFS_PACKET_MAX);
- /* Request sent successfully. Copy the reply and wake the client. */
- HgfsCompleteReq(req, replyPacket, payloadSize);
- LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendUnsentReqs: Backdoor "
- "reply received\n"));
- } else {
+ compat_mutex_lock(&bdChannel.connLock);
- /* Pass the error into the request. */
- req->state = HGFS_REQ_STATE_ERROR;
- list_del_init(&req->list);
- LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendUnsentReqs: Backdoor "
- "error\n"));
- HgfsWakeWaitingClient(req);
+ if (bdChannel.status != HGFS_CHANNEL_CONNECTED) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: Backdoor not opened\n",
+ __FUNCTION__));
+ compat_mutex_unlock(&bdChannel.connLock);
+ return -ENOTCONN;
+ }
- /*
- * If the channel was previously open, make sure it's dead and gone
- * now. We do this because subsequent requests deserve a chance to
- * reopen it.
- */
- HgfsBd_CloseBackdoor(&hgfsRpcOut);
- }
+ payloadSize = req->payloadSize;
+ LOG(8, ("VMware hgfs: %s: backdoor sending.\n", __FUNCTION__));
+ ret = HgfsBd_Dispatch(bdChannel.priv, HGFS_REQ_PAYLOAD(req), &payloadSize,
+ &replyPacket);
+ if (ret == 0) {
+ /* Request sent successfully. Copy the reply and wake the client. */
+ ASSERT(replyPacket);
+ HgfsCompleteReq(req, replyPacket, payloadSize);
+ LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendUnsentReqs: Backdoor "
+ "reply received\n"));
+ } else {
+ bdChannel.priv = NULL;
+ bdChannel.status = HGFS_CHANNEL_DISCONNECTED;
}
- spin_unlock(&hgfsBigLock);
-}
+ compat_mutex_unlock(&bdChannel.connLock);
+ return ret;
+}
-/*
- * Public function implementations.
- */
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
- * HgfsResetOps --
+ * HgfsBdChannelExit --
*
- * Reset ops with more than one opcode back to the desired opcode.
+ * Tear down the channel.
*
* Results:
- * None.
+ * None
*
* Side effects:
- * None.
+ * None
*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
-void
-HgfsResetOps(void)
+static void
+HgfsBdChannelExit(void)
{
- atomic_set(&hgfsVersionOpen, HGFS_OP_OPEN_V3);
- atomic_set(&hgfsVersionRead, HGFS_OP_READ_V3);
- atomic_set(&hgfsVersionWrite, HGFS_OP_WRITE_V3);
- atomic_set(&hgfsVersionClose, HGFS_OP_CLOSE_V3);
- atomic_set(&hgfsVersionSearchOpen, HGFS_OP_SEARCH_OPEN_V3);
- atomic_set(&hgfsVersionSearchRead, HGFS_OP_SEARCH_READ_V3);
- atomic_set(&hgfsVersionSearchClose, HGFS_OP_SEARCH_CLOSE_V3);
- atomic_set(&hgfsVersionGetattr, HGFS_OP_GETATTR_V3);
- atomic_set(&hgfsVersionSetattr, HGFS_OP_SETATTR_V3);
- atomic_set(&hgfsVersionCreateDir, HGFS_OP_CREATE_DIR_V3);
- atomic_set(&hgfsVersionDeleteFile, HGFS_OP_DELETE_FILE_V3);
- atomic_set(&hgfsVersionDeleteDir, HGFS_OP_DELETE_DIR_V3);
- atomic_set(&hgfsVersionRename, HGFS_OP_RENAME_V3);
- atomic_set(&hgfsVersionQueryVolumeInfo, HGFS_OP_QUERY_VOLUME_INFO_V3);
- atomic_set(&hgfsVersionCreateSymlink, HGFS_OP_CREATE_SYMLINK_V3);
+ compat_mutex_lock(&bdChannel.connLock);
+ if (bdChannel.priv != NULL) {
+ HgfsBd_CloseBackdoor((RpcOut **)&bdChannel.priv);
+ ASSERT(bdChannel.priv == NULL);
+ }
+ bdChannel.status = HGFS_CHANNEL_UNINITIALIZED;
+ compat_mutex_unlock(&bdChannel.connLock);
}
/*
*----------------------------------------------------------------------
*
- * HgfsBdHandler --
+ * HgfsBdChannelInit --
*
- * Function run in background thread to pick up HGFS requests from
- * the filesystem half of the driver, send them over the backdoor,
- * get replies, and send them back to the filesystem.
- *
- * Note that this function is called out of the kthread subsystem or, in
- * older kernels, a similar abstraction built in compat_kthread.h.
+ * Initialize backdoor channel.
*
* Results:
- * Always returns zero.
+ * Always return TRUE.
*
* Side effects:
- * Processes entries from hgfsReqQ.
+ * None
*
*----------------------------------------------------------------------
*/
-int
-HgfsBdHandler(void *data) // Ignored
+Bool
+HgfsBdChannelInit(void)
{
- LOG(6, (KERN_DEBUG "VMware hgfs: HgfsBdHandler: Thread starting\n"));
- compat_set_freezable();
-
- for (;;) {
-
- /* Sleep, waiting for a request or exit. */
- wait_event_interruptible(hgfsReqThreadWait,
- test_bit(HGFS_REQ_THREAD_SEND,
- &hgfsReqThreadFlags) ||
- compat_wait_check_freezing() ||
- compat_kthread_should_stop());
-
- /*
- * First, check for suspend. I'm not convinced that this actually
- * has to come first, but whatever.
- */
- if (compat_try_to_freeze()) {
- LOG(6, (KERN_DEBUG
- "VMware hgfs: HgfsBdHandler: Closing backdoor after resume\n"));
- HgfsBd_CloseBackdoor(&hgfsRpcOut);
- }
-
- /* Send outgoing requests. */
- if (test_and_clear_bit(HGFS_REQ_THREAD_SEND, &hgfsReqThreadFlags)) {
- LOG(8, (KERN_DEBUG "VMware hgfs: HgfsBdHandler: Sending requests\n"));
- HgfsSendUnsentReqs();
- }
-
- /* Kill yourself. */
- if (compat_kthread_should_stop()) {
- LOG(6, (KERN_DEBUG "VMware hgfs: HgfsBdHandler: Told to exit\n"));
- break;
- }
- }
-
- LOG(6, (KERN_DEBUG "VMware hgfs: HgfsBdHandler: Closing backdoor\n"));
- HgfsBd_CloseBackdoor(&hgfsRpcOut);
-
- LOG(6, (KERN_DEBUG "VMware hgfs: HgfsBdHandler: Thread exiting\n"));
- return 0;
+ bdChannel.name = "backdoor";
+ bdChannel.ops.open = HgfsBdChannelOpen;
+ bdChannel.ops.close = HgfsBdChannelClose;
+ bdChannel.ops.send = HgfsBdChannelSend;
+ bdChannel.ops.recv = NULL;
+ bdChannel.ops.exit = HgfsBdChannelExit;
+ bdChannel.priv = NULL;
+ compat_mutex_init(&bdChannel.connLock);
+ bdChannel.status = HGFS_CHANNEL_DISCONNECTED;
+
+ return TRUE;
}
/*
* bdhandler.h --
*
- * Background thread for handling backdoor requests and replies.
+ * Backdoor channel implementation.
*/
#ifndef _HGFS_DRIVER_BDHANDLER_H_
#define _HGFS_DRIVER_BDHANDLER_H_
-/* Public functions (with respect to the entire module). */
-void HgfsResetOps(void);
-int HgfsBdHandler(void *data);
+#include "transport.h"
+
+Bool HgfsBdChannelInit(void);
+
+extern HgfsTransportChannel bdChannel;
#endif // _HGFS_DRIVER_BDHANDLER_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_COMPLETION_H__
-# define __COMPAT_COMPLETION_H__
-
-/*
- * The kernel's completion objects were made available for module use in 2.4.9.
- *
- * Between 2.4.0 and 2.4.9, we implement completions on our own using
- * waitqueues and counters. This was done so that we could safely support
- * functions like complete_all(), which cannot be implemented using semaphores.
- *
- * Prior to that, the waitqueue API is substantially different, and since none
- * of our modules that are built against older kernels need complete_all(),
- * we fallback on a simple semaphore-based implementation.
- */
-
-/*
- * Native completions.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#include <linux/completion.h>
-#define compat_completion struct completion
-#define compat_init_completion(comp) init_completion(comp)
-#define COMPAT_DECLARE_COMPLETION DECLARE_COMPLETION
-#define compat_wait_for_completion(comp) wait_for_completion(comp)
-#define compat_complete(comp) complete(comp)
-
-/* complete_all() was exported in 2.6.6. */
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
-# include "compat_wait.h"
-# include "compat_list.h"
-# include "compat_spinlock.h"
-# include "compat_sched.h"
-# define compat_complete_all(x) \
- ({ \
- struct list_head *currLinks; \
- spin_lock(&(x)->wait.lock); \
- (x)->done += UINT_MAX/2; \
- \
- list_for_each(currLinks, &(x)->wait.task_list) { \
- wait_queue_t *currQueue = list_entry(currLinks, wait_queue_t, task_list); \
- wake_up_process(currQueue->task); \
- } \
- spin_unlock(&(x)->wait.lock); \
- })
-# else
-# define compat_complete_all complete_all
-# endif
-
-/*
- * Completions via waitqueues.
- */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-
-/*
- * Kernel completions in 2.4.9 and beyond use a counter and a waitqueue, and
- * our implementation is quite similar. Because __wake_up_common() is not
- * exported, our implementations of compat_complete() and compat_complete_all()
- * are somewhat racy: the counter is incremented outside of the waitqueue's
- * lock.
- *
- * As a result, our completion cannot guarantee in-order wake ups. For example,
- * suppose thread A is entering compat_complete(), thread B is sleeping inside
- * compat_wait_for_completion(), and thread C is just now entering
- * compat_wait_for_completion(). If Thread A is scheduled first and increments
- * the counter, then gets swapped out, thread C may get scheduled and will
- * quickly go through compat_wait_for_completion() (since done != 0) while
- * thread B continues to sleep, even though thread B should have been the one
- * to wake up.
- */
-
-#include <asm/current.h>
-#include "compat_sched.h"
-#include "compat_list.h"
-#include <linux/smp_lock.h> // for lock_kernel()/unlock_kernel()
-#include "compat_wait.h"
-
-typedef struct compat_completion {
- unsigned int done;
- wait_queue_head_t wq;
-} compat_completion;
-
-#define compat_init_completion(comp) do { \
- (comp)->done = 0; \
- init_waitqueue_head(&(comp)->wq); \
-} while (0)
-#define COMPAT_DECLARE_COMPLETION(comp) \
- compat_completion comp = { \
- .done = 0, \
- .wq = __WAIT_QUEUE_HEAD_INITIALIZER((comp).wq), \
- }
-
-/*
- * Locking and unlocking the kernel lock here ensures that the thread
- * is no longer running in module code: compat_complete_and_exit
- * performs the sequence { lock_kernel(); up(comp); compat_exit(); }, with
- * the final unlock_kernel performed implicitly by the resident kernel
- * in do_exit.
- */
-#define compat_wait_for_completion(comp) do { \
- spin_lock_irq(&(comp)->wq.lock); \
- if (!(comp)->done) { \
- DECLARE_WAITQUEUE(wait, current); \
- wait.flags |= WQ_FLAG_EXCLUSIVE; \
- __add_wait_queue_tail(&(comp)->wq, &wait); \
- do { \
- __set_current_state(TASK_UNINTERRUPTIBLE); \
- spin_unlock_irq(&(comp)->wq.lock); \
- schedule(); \
- spin_lock_irq(&(comp)->wq.lock); \
- } while (!(comp)->done); \
- __remove_wait_queue(&(comp)->wq, &wait); \
- } \
- (comp)->done--; \
- spin_unlock_irq(&(comp)->wq.lock); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-/* XXX: I don't think I need to touch the BKL. */
-#define compat_complete(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done++; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up(&(comp)->wq); \
-} while (0)
-
-#define compat_complete_all(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done += UINT_MAX / 2; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up_all(&(comp)->wq); \
-} while (0)
-
-/*
- * Completions via semaphores.
- */
-#else
-
-#include "compat_semaphore.h"
-#define compat_completion struct semaphore
-#define compat_init_completion(comp) init_MUTEX_LOCKED(comp)
-#define COMPAT_DECLARE_COMPLETION(comp) DECLARE_MUTEX_LOCKED(comp)
-
-#define compat_wait_for_completion(comp) do { \
- down(comp); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-#define compat_complete(comp) up(comp)
-
-#endif
-
-#endif /* __COMPAT_COMPLETION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_FILE_H__
-# define __COMPAT_FILE_H__
-
-
-/* The fput() API is modified in 2.2.0 --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define compat_fput(_file) fput(_file)
-#else
-# define compat_fput(_file) fput(_file, (_file)->f_inode)
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-# define compat_get_file(_file) get_file(_file)
-# define compat_file_count(_file) file_count(_file)
-#else
-# define compat_get_file(_file) (_file)->f_count++
-# define compat_file_count(_file) (_file)->f_count
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 4)
-# define compat_filp_close(_file, _files) filp_close(_file, _files)
-#else
-static inline void compat_filp_close(struct file* filp, fl_owner_t files) {
- if (filp->f_op && filp->f_op->flush) {
- filp->f_op->flush(filp);
- }
- /*
- * Hopefully there are no locks to release on this filp.
- * locks_remove_posix is not exported so we cannot use it...
- */
- fput(filp);
-}
-#endif
-
-
-#endif /* __COMPAT_FILE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_FS_H__
-# define __COMPAT_FS_H__
-
-#include <linux/fs.h>
-
-/*
- * 2.6.5+ kernels define FS_BINARY_MOUNTDATA. Since it didn't exist and
- * wasn't used prior, it's safe to define it to zero.
- */
-
-#ifndef FS_BINARY_MOUNTDATA
-#define FS_BINARY_MOUNTDATA 0
-#endif
-
-/*
- * MAX_LFS_FILESIZE wasn't defined until 2.5.4.
- */
-#ifndef MAX_LFS_FILESIZE
-# include <linux/pagemap.h>
-# if BITS_PER_LONG == 32
-# define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG - 1)) - 1)
-# elif BITS_PER_LONG == 64
-# define MAX_LFS_FILESIZE 0x7fffffffffffffffUL
-# endif
-#endif
-
-
-/*
- * sendfile as a VFS op was born in 2.5.30. Unfortunately, it also changed
- * signatures, first in 2.5.47, then again in 2.5.70, then again in 2.6.8.
- * Luckily, the 2.6.8+ signature is the same as the 2.5.47 signature. And
- * as of 2.6.23-rc1 sendfile is gone, replaced by splice_read...
- *
- * Let's not support sendfile from 2.5.30 to 2.5.47, because the 2.5.30
- * signature is much different and file_send_actor isn't externed.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#define VMW_SENDFILE_NONE
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
-#define VMW_SENDFILE_NEW
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 70)
-#define VMW_SENDFILE_OLD
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 47)
-#define VMW_SENDFILE_NEW
-#else
-#define VMW_SENDFILE_NONE
-#endif
-
-/*
- * splice_read is there since 2.6.17, but let's avoid 2.6.17-rcX kernels...
- * After all nobody is using splice system call until 2.6.23 using it to
- * implement sendfile.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
-#define VMW_SPLICE_READ 1
-#endif
-
-/*
- * Filesystems wishing to use generic page cache read/write routines are
- * supposed to implement aio_read and aio_write (calling into
- * generic_file_aio_read() and generic_file_aio_write() if necessary).
- *
- * The VFS exports do_sync_read() and do_sync_write() as the "new"
- * generic_file_read() and generic_file_write(), but filesystems need not
- * actually implement read and write- the VFS will automatically call
- * do_sync_write() and do_sync_read() when applications invoke the standard
- * read() and write() system calls.
- *
- * In 2.6.19, generic_file_read() and generic_file_write() were removed,
- * necessitating this change. AIO dates as far back as 2.5.42, but the API has
- * changed over time, so for simplicity, we'll only enable it from 2.6.19 and
- * on.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
-# define VMW_USE_AIO
-#endif
-
-
-/*
- * The alloc_inode and destroy_inode VFS ops didn't exist prior to 2.4.21.
- * Without these functions, file systems can't embed inodes.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 21)
-# define VMW_EMBED_INODE
-#endif
-
-
-/*
- * iget() was removed from the VFS as of 2.6.25-rc1. The replacement for iget()
- * is iget_locked() which was added in 2.5.17.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 17)
-# define VMW_USE_IGET_LOCKED
-#endif
-
-/*
- * parent_ino was born in 2.5.5. For older kernels, let's use 2.5.5
- * implementation. It uses the dcache lock which is OK because per-dentry
- * locking appeared after 2.5.5.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-#define compat_parent_ino(dentry) parent_ino(dentry)
-#else
-#define compat_parent_ino(dentry) \
-({ \
- ino_t res; \
- spin_lock(&dcache_lock); \
- res = dentry->d_parent->d_inode->i_ino; \
- spin_unlock(&dcache_lock); \
- res; \
-})
-#endif
-
-
-/*
- * putname changed to __putname in 2.6.6.
- */
-#define compat___getname() __getname()
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
-#define compat___putname(name) putname(name)
-#else
-#define compat___putname(name) __putname(name)
-#endif
-
-
-/*
- * inc_nlink, drop_nlink, and clear_nlink were added in 2.6.19.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#define compat_inc_nlink(inode) ((inode)->i_nlink++)
-#define compat_drop_nlink(inode) ((inode)->i_nlink--)
-#define compat_clear_nlink(inode) ((inode)->i_nlink = 0)
-#else
-#define compat_inc_nlink(inode) inc_nlink(inode)
-#define compat_drop_nlink(inode) drop_nlink(inode)
-#define compat_clear_nlink(inode) clear_nlink(inode)
-#endif
-
-
-/*
- * i_size_write and i_size_read were introduced in 2.6.0-test1
- * (though we'll look for them as of 2.6.1). They employ slightly different
- * locking in order to guarantee atomicity, depending on the length of a long,
- * whether the kernel is SMP, or whether the kernel is preemptible. Prior to
- * i_size_write and i_size_read, there was no such locking, so that's the
- * behavior we'll emulate.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 1)
-#define compat_i_size_read(inode) ((inode)->i_size)
-#define compat_i_size_write(inode, size) ((inode)->i_size = size)
-#else
-#define compat_i_size_read(inode) i_size_read(inode)
-#define compat_i_size_write(inode, size) i_size_write(inode, size)
-#endif
-
-
-/*
- * filemap_fdatawrite was introduced in 2.5.12. Prior to that, modules used
- * filemap_fdatasync instead. In 2.4.18, both filemap_fdatawrite and
- * filemap_fdatawait began returning status codes. Prior to that, they were
- * void functions, so we'll just have them return 0.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 18)
-#define compat_filemap_fdatawrite(mapping) \
-({ \
- int result = 0; \
- filemap_fdatasync(mapping); \
- result; \
-})
-#define compat_filemap_fdatawait(mapping) \
-({ \
- int result = 0; \
- filemap_fdatawait(mapping); \
- result; \
-})
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12)
-#define compat_filemap_fdatawrite(mapping) filemap_fdatasync(mapping)
-#define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping)
-#else
-#define compat_filemap_fdatawrite(mapping) filemap_fdatawrite(mapping)
-#define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping)
-#endif
-
-
-/*
- * filemap_write_and_wait was introduced in 2.6.6 and exported for module use
- * in 2.6.16. It's really just a simple wrapper around filemap_fdatawrite and
- * and filemap_fdatawait, which initiates a flush of all dirty pages, then
- * waits for the pages to flush. The implementation here is a simplified form
- * of the one found in 2.6.20-rc3.
- *
- * Unfortunately, it just isn't possible to implement this prior to 2.4.5, when
- * neither filemap_fdatawait nor filemap_fdatasync were exported for module
- * use. So we'll define it out and hope for the best.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 5)
-#define compat_filemap_write_and_wait(mapping)
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
-#define compat_filemap_write_and_wait(mapping) \
-({ \
- int result = 0; \
- if (mapping->nrpages) { \
- result = compat_filemap_fdatawrite(mapping); \
- if (result != -EIO) { \
- int result2 = compat_filemap_fdatawait(mapping); \
- if (!result) { \
- result = result2; \
- } \
- } \
- } \
- result; \
-})
-#else
-#define compat_filemap_write_and_wait(mapping) filemap_write_and_wait(mapping)
-#endif
-
-
-/*
- * invalidate_remote_inode was introduced in 2.6.0-test5. Prior to that,
- * filesystems wishing to invalidate pages belonging to an inode called
- * invalidate_inode_pages.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-#define compat_invalidate_remote_inode(inode) invalidate_inode_pages(inode)
-#else
-#define compat_invalidate_remote_inode(inode) invalidate_remote_inode(inode)
-#endif
-
-#endif /* __COMPAT_FS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_HIGHMEM_H__
-# define __COMPAT_HIGHMEM_H__
-
-
-/*
- * BIGMEM (4 GB) support appeared in 2.3.16: kmap() API added
- * HIGHMEM (4 GB + 64 GB) support appeared in 2.3.23: kmap() API modified
- * In 2.3.27, kmap() API modified again
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 27)
-# include <linux/highmem.h>
-#else
-/* For page_address --hpreg */
-# include <linux/pagemap.h>
-
-# define kmap(_page) (void*)page_address(_page)
-# define kunmap(_page)
-#endif
-
-#endif /* __COMPAT_HIGHMEM_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_KERNEL_H__
-# define __COMPAT_KERNEL_H__
-
-#include <asm/unistd.h>
-#include <linux/kernel.h>
-
-/*
- * container_of was introduced in 2.5.28 but it's easier to check like this.
- */
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-/*
- * wait_for_completion and friends did not exist before 2.4.9.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#define compat_complete_and_exit(comp, status) complete_and_exit(comp, status)
-
-#else
-
-#include "compat_completion.h"
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-#define __NR_compat_exit __NR_exit
-static inline _syscall1(int, compat_exit, int, exit_code);
-
-/*
- * See compat_wait_for_completion in compat_completion.h.
- * compat_exit implicitly performs an unlock_kernel, in resident code,
- * ensuring that the thread is no longer running in module code when the
- * module is unloaded.
- */
-#define compat_complete_and_exit(comp, status) do { \
- lock_kernel(); \
- compat_complete(comp); \
- compat_exit(status); \
-} while (0)
-
-#endif
-
-/*
- * vsnprintf became available in 2.4.10. For older kernels, just fall back on
- * vsprintf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define vsnprintf(str, size, fmt, args) vsprintf(str, fmt, args)
-#endif
-
-#endif /* __COMPAT_KERNEL_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_LIST_H__
-# define __COMPAT_LIST_H__
-
-#include <linux/list.h>
-
-/*
- * list_add_tail is with us since 2.4.0, or something like that.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define list_add_tail(newe, head) do { \
- struct list_head *__h = (head); \
- __list_add((newe), __h->prev, __h); \
-} while (0)
-#endif
-
-/*
- * list_for_each_safe() showed up in 2.4.10, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_safe
-# define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-#endif
-
-/*
- * list_for_each_entry() showed up in 2.4.20, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_entry
-# define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-#endif
-
-#endif /* __COMPAT_LIST_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_MM_H__
-# define __COMPAT_MM_H__
-
-
-#include <linux/mm.h>
-
-
-/* The get_page() API appeared in 2.3.7 --hpreg */
-/* Sometime during development it became function instead of macro --petr */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(get_page)
-# define get_page(_page) atomic_inc(&(_page)->count)
-/* The __free_page() API is exported in 2.1.67 --hpreg */
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 67)
-# define put_page __free_page
-# else
-# include "compat_page.h"
-
-# define page_to_phys(_page) (page_to_pfn(_page) << PAGE_SHIFT)
-# define put_page(_page) free_page(page_to_phys(_page))
-# endif
-#endif
-
-
-/* page_count() is 2.4.0 invention. Unfortunately unavailable in some RedHat
- * kernels (for example 2.4.21-4-RHEL3). */
-/* It is function since 2.6.0, and hopefully RedHat will not play silly games
- * with mm_inline.h again... */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(page_count)
-# define page_count(page) atomic_read(&(page)->count)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-# define compat_vm_pgoff(vma) ((vma)->vm_offset >> PAGE_SHIFT)
-
-static inline unsigned long compat_do_mmap_pgoff(struct file *file, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long pgoff)
-{
- unsigned long ret = -EINVAL;
-
- if (pgoff < 1 << (32 - PAGE_SHIFT)) {
- ret = do_mmap(file, addr, len, prot, flag, pgoff << PAGE_SHIFT);
- }
- return ret;
-}
-
-#else
-# define compat_vm_pgoff(vma) (vma)->vm_pgoff
-# ifdef VMW_SKAS_MMAP
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(current->mm, f, a, l, p, g, o)
-# else
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(f, a, l, p, g, o)
-# endif
-#endif
-
-
-/* 2.2.x uses 0 instead of some define */
-#ifndef NOPAGE_SIGBUS
-#define NOPAGE_SIGBUS (0)
-#endif
-
-
-/* 2.2.x does not have HIGHMEM support */
-#ifndef GFP_HIGHUSER
-#define GFP_HIGHUSER (GFP_USER)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-
-#include "compat_page.h"
-
-static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
-{
- unsigned long addr;
-
- addr = __get_free_pages(gfp_mask, order);
- if (!addr) {
- return NULL;
- }
- return virt_to_page(addr);
-}
-#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
-
-#endif
-
-/*
- * In 2.4.14, the logic behind the UnlockPage macro was moved to the
- * unlock_page() function. Later (in 2.5.12), the UnlockPage macro was removed
- * altogether, and nowadays everyone uses unlock_page().
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 14)
-#define compat_unlock_page(page) UnlockPage(page)
-#else
-#define compat_unlock_page(page) unlock_page(page)
-#endif
-
-/*
- * In 2.4.10, vmtruncate was changed from returning void to returning int.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define compat_vmtruncate(inode, size) \
-({ \
- int result = 0; \
- vmtruncate(inode, size); \
- result; \
-})
-#else
-#define compat_vmtruncate(inode, size) vmtruncate(inode, size)
-#endif
-
-
-#endif /* __COMPAT_MM_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_NAMEI_H__
-# define __COMPAT_NAMEI_H__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18)
-#include <linux/namei.h>
-#endif
-
-/*
- * In 2.6.25-rc2, dentry and mount objects were removed from the nameidata
- * struct. They were both replaced with a struct path.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
-#define compat_vmw_nd_to_dentry(nd) (nd).path.dentry
-#else
-#define compat_vmw_nd_to_dentry(nd) (nd).dentry
-#endif
-
-/* In 2.6.25-rc2, path_release(&nd) was replaced with path_put(&nd.path). */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
-#define compat_path_release(nd) path_put(&(nd)->path)
-#else
-#define compat_path_release(nd) path_release(nd)
-#endif
-
-/* path_lookup was exported in 2.4.25 */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
-#define compat_path_lookup(path, flags, nd) path_lookup(path, flags, nd)
-#else
-#define compat_path_lookup(path, flags, nd) \
- ({ \
- int ret = 0; \
- if (path_init(path, flags, nd)) { \
- ret = path_walk(path, nd); \
- } \
- ret; \
- })
-#endif
-
-#endif /* __COMPAT_NAMEI_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_PAGE_H__
-# define __COMPAT_PAGE_H__
-
-
-#include <linux/mm.h>
-#include <asm/page.h>
-
-
-/* The pfn_to_page() API appeared in 2.5.14 and changed to function during 2.6.x */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pfn_to_page)
-# define pfn_to_page(_pfn) (mem_map + (_pfn))
-# define page_to_pfn(_page) ((_page) - mem_map)
-#endif
-
-
-/* The virt_to_page() API appeared in 2.4.0 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(virt_to_page)
-# define virt_to_page(_kvAddr) pfn_to_page(MAP_NR(_kvAddr))
-#endif
-
-
-/*
- * The get_order() API appeared at some point in 2.3.x, and was then backported
- * in 2.2.17-21mdk and in the stock 2.2.18. Because we can only detect its
- * definition through makefile tricks, we provide our own for now --hpreg
- */
-static inline int
-compat_get_order(unsigned long size) // IN
-{
- int order;
-
- size = (size - 1) >> (PAGE_SHIFT - 1);
- order = -1;
- do {
- size >>= 1;
- order++;
- } while (size);
-
- return order;
-}
-
-/*
- * BUG() was added to <asm/page.h> in 2.2.18, and was moved to <asm/bug.h>
- * in 2.5.58.
- *
- * XXX: Technically, this belongs in some sort of "compat_asm_page.h" file, but
- * since our compatibility wrappers don't distinguish between <asm/xxx.h> and
- * <linux/xxx.h>, putting it here is reasonable.
- */
-#ifndef BUG
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- __asm__ __volatile__(".byte 0x0f,0x0b"); \
-} while (0)
-#endif
-
-#endif /* __COMPAT_PAGE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SCHED_H__
-# define __COMPAT_SCHED_H__
-
-
-#include <linux/sched.h>
-
-/* CLONE_KERNEL available in 2.5.35 and higher. */
-#ifndef CLONE_KERNEL
-#define CLONE_KERNEL CLONE_FILES | CLONE_FS | CLONE_SIGHAND
-#endif
-
-/* TASK_COMM_LEN become available in 2.6.11. */
-#ifndef TASK_COMM_LEN
-#define TASK_COMM_LEN 16
-#endif
-
-/* The capable() API appeared in 2.1.92 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 92)
-# define capable(_capability) suser()
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-# define need_resched() need_resched
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define need_resched() (current->need_resched)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define cond_resched() (need_resched() ? schedule() : (void) 0)
-#endif
-
-/* Oh well. We need yield... Happy us! */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
-# ifdef __x86_64__
-# define compat_yield() there_is_nothing_like_yield()
-# else
-# include <linux/unistd.h>
-# include <linux/kernel.h>
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-# define __NR_compat_yield __NR_sched_yield
-static inline _syscall0(int, compat_yield);
-# endif
-#else
-# define compat_yield() yield()
-#endif
-
-
-/*
- * Since 2.5.34 there are two methods to enumerate tasks:
- * for_each_process(p) { ... } which enumerates only tasks and
- * do_each_thread(g,t) { ... } while_each_thread(g,t) which enumerates
- * also threads even if they share same pid.
- */
-#ifndef for_each_process
-# define for_each_process(p) for_each_task(p)
-#endif
-
-#ifndef do_each_thread
-# define do_each_thread(g, t) for_each_task(g) { t = g; do
-# define while_each_thread(g, t) while (0) }
-#endif
-
-
-/*
- * Lock for signal mask is moving target...
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 40) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_sigmask_lock sigmask_lock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 60) && !defined(INIT_SIGHAND)
-/* RedHat's 2.4.x with first version of NPTL support, or 2.5.40 to 2.5.59 */
-#define compat_sigmask_lock sig->siglock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-/* RedHat's 2.4.x with second version of NPTL support, or 2.5.60+. */
-#define compat_sigmask_lock sighand->siglock
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(current, ¤t->blocked, (siginfo_ptr))
-#endif
-#endif
-
-/*
- * recalc_sigpending() had task argument in the past
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 29) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_recalc_sigpending() recalc_sigpending(current)
-#else
-/* RedHat's 2.4.x with NPTL support, or 2.5.29+ */
-#define compat_recalc_sigpending() recalc_sigpending()
-#endif
-
-
-/*
- * reparent_to_init() was introduced in 2.4.8. In 2.5.38 (or possibly
- * earlier, but later than 2.5.31) a call to it was added into
- * daemonize(), so compat_daemonize no longer needs to call it.
- *
- * In 2.4.x kernels reparent_to_init() forgets to do correct refcounting
- * on current->user. It is better to count one too many than one too few...
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 38)
-#define compat_reparent_to_init() do { \
- reparent_to_init(); \
- atomic_inc(¤t->user->__count); \
- } while (0)
-#else
-#define compat_reparent_to_init() do {} while (0)
-#endif
-
-
-/*
- * daemonize appeared in 2.2.18. Except 2.2.17-4-RH7.0, which has it too.
- * Fortunately 2.2.17-4-RH7.0 uses versioned symbols, so we can check
- * its existence with defined().
- */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) && !defined(daemonize)
-static inline void daemonize(void) {
- struct fs_struct *fs;
-
- exit_mm(current);
- current->session = 1;
- current->pgrp = 1;
- exit_fs(current);
- fs = init_task.fs;
- current->fs = fs;
- atomic_inc(&fs->count);
-}
-#endif
-
-
-/*
- * flush_signals acquires sighand->siglock since 2.5.61... Verify RH's kernels!
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_flush_signals(task) do { \
- spin_lock_irq(&task->compat_sigmask_lock); \
- flush_signals(task); \
- spin_unlock_irq(&task->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_flush_signals(task) flush_signals(task)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_allow_signal(signr) do { \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigdelset(¤t->blocked, signr); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_allow_signal(signr) allow_signal(signr)
-#endif
-
-/*
- * daemonize can set process name since 2.5.61. Prior to 2.5.61, daemonize
- * didn't block signals on our behalf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_daemonize(x...) \
-({ \
- /* Beware! No snprintf here, so verify arguments! */ \
- sprintf(current->comm, x); \
- \
- /* Block all signals. */ \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigfillset(¤t->blocked); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- compat_flush_signals(current); \
- \
- daemonize(); \
- compat_reparent_to_init(); \
-})
-#else
-#define compat_daemonize(x...) daemonize(x)
-#endif
-
-
-/*
- * set priority for specified thread. Exists on 2.6.x kernels and some
- * 2.4.x vendor's kernels.
- */
-#if defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) set_user_nice((task), (n))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define compat_set_user_nice(task, n) do { (task)->priority = 20 - (n); } while (0)
-#elif !defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) do { (task)->nice = (n); } while (0)
-#endif
-
-/*
- * try to freeze a process. For kernels 2.6.11 or newer, we know how to choose
- * the interface. The problem is that the oldest interface, introduced in
- * 2.5.18, was backported to 2.4.x kernels. So if we're older than 2.6.11,
- * we'll decide what to do based on whether or not swsusp was configured
- * for the kernel. For kernels 2.6.20 and newer, we'll also need to include
- * freezer.h since the try_to_freeze definition was pulled out of sched.h.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-#include <linux/freezer.h>
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) || defined(VMW_TL10S64_WORKAROUND)
-#define compat_try_to_freeze() try_to_freeze()
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
-#define compat_try_to_freeze() try_to_freeze(PF_FREEZE)
-#elif defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_SOFTWARE_SUSPEND2)
-#include "compat_mm.h"
-#include <linux/errno.h>
-#include <linux/suspend.h>
-static inline int compat_try_to_freeze(void) {
- if (current->flags & PF_FREEZE) {
- refrigerator(PF_FREEZE);
- return 1;
- } else {
- return 0;
- }
-}
-#else
-static inline int compat_try_to_freeze(void) { return 0; }
-#endif
-
-/*
- * As of 2.6.23-rc1, kernel threads are no longer freezable by
- * default. Instead, kernel threads that need to be frozen must opt-in
- * by calling set_freezable() as soon as the thread is created.
- */
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
-#define compat_set_freezable() do { set_freezable(); } while (0)
-#else
-#define compat_set_freezable() do {} while (0)
-#endif
-
-/*
- * Around 2.6.27 kernel stopped sending signals to kernel
- * threads being frozen, instead threads have to check
- * freezing() or use wait_event_freezable(). Unfortunately
- * wait_event_freezable() completely hides the fact that
- * thread was frozen from calling code and sometimes we do
- * want to know that.
- */
-#ifdef PF_FREEZER_NOSIG
-#define compat_wait_check_freezing() freezing(current)
-#else
-#define compat_wait_check_freezing() (0)
-#endif
-
-/*
- * Since 2.6.27-rc2 kill_proc() is gone... Replacement (GPL-only!)
- * API is available since 2.6.19. Use them from 2.6.27-rc1 up.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-typedef int compat_pid;
-#define compat_find_get_pid(pid) (pid)
-#define compat_put_pid(pid) do { } while (0)
-#define compat_kill_pid(pid, sig, flag) kill_proc(pid, sig, flag)
-#else
-typedef struct pid * compat_pid;
-#define compat_find_get_pid(pid) find_get_pid(pid)
-#define compat_put_pid(pid) put_pid(pid)
-#define compat_kill_pid(pid, sig, flag) kill_pid(pid, sig, flag)
-#endif
-
-
-#endif /* __COMPAT_SCHED_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SEMAPHORE_H__
-# define __COMPAT_SEMAPHORE_H__
-
-
-/* <= 2.6.25 have asm only, 2.6.26 has both, and 2.6.27-rc2+ has linux only. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-# include <asm/semaphore.h>
-#else
-# include <linux/semaphore.h>
-#endif
-
-
-/*
-* The init_MUTEX_LOCKED() API appeared in 2.2.18, and is also in
-* 2.2.17-21mdk --hpreg
-*/
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
- #ifndef init_MUTEX_LOCKED
- #define init_MUTEX_LOCKED(_sem) *(_sem) = MUTEX_LOCKED
- #endif
- #ifndef DECLARE_MUTEX
- #define DECLARE_MUTEX(name) struct semaphore name = MUTEX
- #endif
- #ifndef DECLARE_MUTEX_LOCKED
- #define DECLARE_MUTEX_LOCKED(name) struct semaphore name = MUTEX_LOCKED
- #endif
-#endif
-
-
-#endif /* __COMPAT_SEMAPHORE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SLAB_H__
-# define __COMPAT_SLAB_H__
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# include <linux/slab.h>
-#else
-# include <linux/malloc.h>
-#endif
-
-/*
- * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache
- * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and
- * afterwards it was renamed to kmem_cache. Here we keep things simple and use
- * the accepted typedef until it became deprecated, at which point we switch
- * over to the kmem_cache name.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-# define compat_kmem_cache struct kmem_cache
-#else
-# define compat_kmem_cache kmem_cache_t
-#endif
-
-/*
- * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags,
- * constructor, and destructor. Then for some time kernel was asserting that
- * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5
- * arguments - destructor is gone.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR)
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor, NULL)
-#else
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor)
-#endif
-
-/*
- * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to
- * prepare (aka "this"), from which cache it came, and some unused flags. After
- * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped...
- * Since 2.6.27-rc2 everything is different again, and ctor has only one argument.
- *
- * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_3_ARGS
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_2_ARGS
-#endif
-
-#if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \
- compat_kmem_cache *cache, \
- unsigned long flags
-#elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \
- void *arg
-#else
-typedef void compat_kmem_cache_ctor(void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg
-#endif
-
-#endif /* __COMPAT_SLAB_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SPINLOCK_H__
-# define __COMPAT_SPINLOCK_H__
-
-
-/*
- * The spin_lock() API appeared in 2.1.25 in asm/smp_lock.h
- * It moved in 2.1.30 to asm/spinlock.h
- * It moved again in 2.3.18 to linux/spinlock.h
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 18)
-# include <linux/spinlock.h>
-#else
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30)
-# include <asm/spinlock.h>
-# else
-typedef struct {} spinlock_t;
-# define spin_lock_init(lock)
-# define spin_lock(lock)
-# define spin_unlock(lock)
-# define spin_lock_irqsave(lock, flags) do { \
- save_flags(flags); \
- cli(); \
- spin_lock(lock); \
- } while (0)
-# define spin_unlock_irqrestore(lock, flags) do { \
- spin_unlock(lock); \
- restore_flags(flags); \
- } while (0)
-# endif
-#endif
-
-
-/*
- * Preempt support was added during 2.5.x development cycle, and later
- * it was backported to 2.4.x. In 2.4.x backport these definitions
- * live in linux/spinlock.h, that's why we put them here (in 2.6.x they
- * are defined in linux/preempt.h which is included by linux/spinlock.h).
- */
-#ifdef CONFIG_PREEMPT
-#define compat_preempt_disable() preempt_disable()
-#define compat_preempt_enable() preempt_enable()
-#else
-#define compat_preempt_disable() do { } while (0)
-#define compat_preempt_enable() do { } while (0)
-#endif
-
-
-#endif /* __COMPAT_SPINLOCK_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_STATFS_H__
-# define __COMPAT_STATFS_H__
-
-/* vfs.h simply include statfs.h, but it knows what directory statfs.h is in. */
-#include <linux/vfs.h>
-
-/* 2.5.74 renamed struct statfs to kstatfs. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 74)
-#define compat_kstatfs kstatfs
-#else
-#define compat_kstatfs statfs
-#endif
-
-#endif /* __COMPAT_STATFS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_STRING_H__
-# define __COMPAT_STRING_H__
-
-#include <linux/string.h>
-
-/*
- * kstrdup was born in 2.6.13. This implementation is almost identical to the
- * one found there.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
-#define compat_kstrdup(s, gfp) kstrdup(s, gfp)
-#else
-#define compat_kstrdup(s, gfp) \
-({ \
- size_t len; \
- char *buf; \
- len = strlen(s) + 1; \
- buf = kmalloc(len, gfp); \
- memcpy(buf, s, len); \
- buf; \
-})
-#endif
-
-#endif /* __COMPAT_STRING_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_UACCESS_H__
-# define __COMPAT_UACCESS_H__
-
-
-/* User space access functions moved in 2.1.7 to asm/uaccess.h --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 7)
-# include <asm/uaccess.h>
-#else
-# include <asm/segment.h>
-#endif
-
-
-/* get_user() API modified in 2.1.4 to take 2 arguments --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 4)
-# define compat_get_user get_user
-#else
-/*
- * We assign 0 to the variable in case of failure to prevent "`_var' might be
- * used uninitialized in this function" compiler warnings. I think it is OK,
- * because the hardware-based version in newer kernels probably has the same
- * semantics and does not guarantee that the value of _var will not be
- * modified, should the access fail --hpreg
- */
-# define compat_get_user(_var, _uvAddr) ({ \
- int _status; \
- \
- _status = verify_area(VERIFY_READ, _uvAddr, sizeof(*(_uvAddr))); \
- if (_status == 0) { \
- (_var) = get_user(_uvAddr); \
- } else { \
- (_var) = 0; \
- } \
- _status; \
-})
-#endif
-
-
-/*
- * The copy_from_user() API appeared in 2.1.4
- *
- * The emulation is not perfect here, but it is conservative: on failure, we
- * always return the total size, instead of the potentially smaller faulty
- * size --hpreg
- *
- * Since 2.5.55 copy_from_user() is no longer macro.
- */
-#if !defined(copy_from_user) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-# define copy_from_user(_to, _from, _size) ( \
- verify_area(VERIFY_READ, _from, _size) \
- ? (_size) \
- : (memcpy_fromfs(_to, _from, _size), 0) \
-)
-# define copy_to_user(_to, _from, _size) ( \
- verify_area(VERIFY_WRITE, _to, _size) \
- ? (_size) \
- : (memcpy_tofs(_to, _from, _size), 0) \
-)
-#endif
-
-
-#endif /* __COMPAT_UACCESS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_WAIT_H__
-# define __COMPAT_WAIT_H__
-
-
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/file.h>
-
-#include "compat_file.h"
-
-
-/*
- * The DECLARE_WAITQUEUE() API appeared in 2.3.1
- * It was back ported in 2.2.18
- *
- * --hpreg
- */
-
-#ifndef DECLARE_WAITQUEUE
-
-typedef struct wait_queue *wait_queue_head_t;
-# define init_waitqueue_head(_headPtr) *(_headPtr) = NULL
-# define DECLARE_WAITQUEUE(_var, _task) \
- struct wait_queue _var = {_task, NULL, }
-
-typedef struct wait_queue wait_queue_t;
-# define init_waitqueue_entry(_wait, _task) ((_wait)->task = (_task))
-
-#endif
-
-/*
- * The 'struct poll_wqueues' appeared in 2.5.48, when global
- * /dev/epoll interface was added. It was backported to the
- * 2.4.20-wolk4.0s.
- */
-
-#ifdef VMW_HAVE_EPOLL // {
-#define compat_poll_wqueues struct poll_wqueues
-#else // } {
-#define compat_poll_wqueues poll_table
-#endif // }
-
-#ifdef VMW_HAVE_EPOLL // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- poll_initwait((table)), \
- (wait) = &(table)->pt \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), \
- poll_initwait(wait) \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#else // } {
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), /* confuse compiler */ \
- (wait) = (poll_table *) __get_free_page(GFP_KERNEL), \
- (wait)->nr = 0, \
- (wait)->entry = (struct poll_table_entry *)((wait) + 1), \
- (wait)->next = NULL \
-)
-
-static inline void
-poll_freewait(poll_table *wait)
-{
- while (wait) {
- struct poll_table_entry * entry;
- poll_table *old;
-
- entry = wait->entry + wait->nr;
- while (wait->nr > 0) {
- wait->nr--;
- entry--;
- remove_wait_queue(entry->wait_address, &entry->wait);
- compat_fput(entry->filp);
- }
- old = wait;
- wait = wait->next;
- free_page((unsigned long) old);
- }
-}
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((wait)) \
-)
-
-#endif // }
-
-/*
- * The wait_event_interruptible_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_interruptible_timeout
-#define __wait_event_interruptible_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_interruptible_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_interruptible_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * The wait_event_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_timeout
-#define __wait_event_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- if (condition) \
- break; \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * DEFINE_WAIT() and friends were added in 2.5.39 and backported to 2.4.28.
- *
- * Unfortunately it is not true. While some distros may have done it the
- * change has never made it into vanilla 2.4 kernel. Instead of testing
- * particular kernel versions let's just test for presence of DEFINE_WAIT
- * when figuring out whether we need to provide replacement implementation
- * or simply alias existing one.
- */
-
-#ifndef DEFINE_WAIT
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DECLARE_WAITQUEUE(_wait, current)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- add_wait_queue(_sleep, _wait); \
- } while (0)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- set_current_state(_state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- remove_wait_queue(_sleep, _wait); \
- } while (0)
-
-#else
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DEFINE_WAIT(_wait)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- finish_wait(_sleep, _wait)
-
-#endif /* #ifndef DEFINE_WAIT */
-
-#endif /* __COMPAT_WAIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * cpName.h --
- *
- * Cross-platform name format used by hgfs.
- *
- */
-
-#ifndef __CP_NAME_H__
-#define __CP_NAME_H__
-
-
-#ifdef __KERNEL__
-# include "driver-config.h"
-# include <linux/string.h>
-#elif defined(__FreeBSD__)
-# if defined(_KERNEL)
-# include <sys/libkern.h>
-# define strchr(s,c) index(s,c)
-# else
-# include <string.h>
-# endif
-#elif defined(__APPLE__) && defined(KERNEL)
-# include <string.h>
-#elif !defined(sun)
-# include <stdlib.h>
-# include <string.h>
-#endif
-
-#include "vm_basic_types.h"
-
-
-/* Status codes for processing share names */
-typedef enum {
- HGFS_NAME_STATUS_COMPLETE, /* Name is complete */
- HGFS_NAME_STATUS_FAILURE, /* Name processing failed */
- HGFS_NAME_STATUS_INCOMPLETE_BASE, /* Name is base of namespace */
- HGFS_NAME_STATUS_INCOMPLETE_ROOT, /* Name is "root" only */
- HGFS_NAME_STATUS_INCOMPLETE_DRIVE, /* Name is "root drive" only */
- HGFS_NAME_STATUS_INCOMPLETE_UNC, /* Name is "root unc" only */
- HGFS_NAME_STATUS_INCOMPLETE_UNC_MACH, /* Name is "root unc <x>" only */
- HGFS_NAME_STATUS_DOES_NOT_EXIST, /* Name does not exist */
- HGFS_NAME_STATUS_ACCESS_DENIED, /* Desired access to share denied */
- HGFS_NAME_STATUS_SYMBOLIC_LINK, /* Name contains a symbolic link */
- HGFS_NAME_STATUS_OUT_OF_MEMORY, /* Out of memory while processing */
- HGFS_NAME_STATUS_TOO_LONG, /* Name has overly long component */
-} HgfsNameStatus;
-
-
-int
-CPName_ConvertTo(char const *nameIn, // IN: The buf to convert
- size_t bufOutSize, // IN: The size of the output buffer
- char *bufOut); // OUT: The output buffer
-
-int
-CPName_LinuxConvertTo(char const *nameIn, // IN: buf to convert
- size_t bufOutSize, // IN: size of the output buffer
- char *bufOut); // OUT: output buffer
-
-int
-CPName_WindowsConvertTo(char const *nameIn, // IN: buf to convert
- size_t bufOutSize, // IN: size of the output buffer
- char *bufOut); // OUT: output buffer
-
-int
-CPName_ConvertFrom(char const **bufIn, // IN/OUT: Input to convert
- size_t *inSize, // IN/OUT: Size of input buffer
- size_t *outSize, // IN/OUT: Size of output buffer
- char **bufOut); // IN/OUT: Output buffer
-
-HgfsNameStatus
-CPName_ConvertFromRoot(char const **bufIn, // IN/OUT: Input to convert
- size_t *inSize, // IN/OUT: Size of input
- size_t *outSize, // IN/OUT: Size of output buf
- char **bufOut); // IN/OUT: Output buffer
-
-int
-CPName_GetComponent(char const *begin, // IN: Beginning of buffer
- char const *end, // IN: End of buffer
- char const **next); // OUT: Next component
-
-char const *
-CPName_Print(char const *in, // IN: Name to print
- size_t size); // IN: Size of name
-
-
-#endif /* __CP_NAME_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * cpNameInt.h --
- *
- * Cross-platform name format used by hgfs.
- *
- */
-
-
-#ifndef __CP_NAME_INT_H__
-#define __CP_NAME_INT_H__
-
-
-#include "vm_basic_types.h"
-
-/*
- * Used by CPName_ConvertFrom
- */
-int
-CPNameConvertFrom(char const **bufIn, // IN/OUT: Input to convert
- size_t *inSize, // IN/OUT: Size of input
- size_t *outSize, // IN/OUT: Size of output buffer
- char **bufOut, // IN/OUT: Output buffer
- char pathSep); // IN: Path separator character
-
-int
-CPNameEscapeAndConvertFrom(char const **bufIn, // IN/OUT: Input to convert
- size_t *inSize, // IN/OUT: Size of input
- size_t *outSize, // IN/OUT: Size of output buffer
- char **bufOut, // IN/OUT: Output buffer
- char pathSep); // IN: Path separator character
-
-/*
- * Common code for CPName_ConvertTo
- */
-int
-CPNameConvertTo(char const *nameIn, // IN: Buf to convert
- size_t bufOutSize, // IN: Size of the output buffer
- char *bufOut, // OUT: Output buffer
- char pathSep); // IN: path separator to use
-
-#endif /* __CP_NAME_INT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * cpLiteName.h --
- *
- * Cross-platform "lite" name format used by hgfs.
- *
- */
-
-#ifndef __CP_NAME_LITE_H__
-#define __CP_NAME_LITE_H__
-
-#if defined(__KERNEL__) && defined(__linux__)
-# include "driver-config.h"
-# include <linux/string.h>
-#elif defined(_KERNEL) && defined(__FreeBSD__)
-# include <sys/libkern.h>
-# define strchr(s,c) index(s,c)
-#else
-# include <string.h>
-#endif
-
-#include "vm_basic_types.h"
-
-void
-CPNameLite_ConvertTo(char *bufIn, // IN/OUT: Input to convert
- size_t inSize, // IN: Size of input buffer
- char pathSep); // IN: Path separator
-
-void
-CPNameLite_ConvertFrom(char *bufIn, // IN/OUT: Input to convert
- size_t inSize, // IN: Size of input buffer
- char pathSep); // IN: Path separator
-
-
-
-#endif /* __CP_NAME_LITE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * dbllnklst.h --
- *
- * Double linked lists
- */
-
-#ifndef _DBLLNKLST_H_
-#define _DBLLNKLST_H_
-
-#include "vm_basic_types.h"
-
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_USERLEVEL
-#include "includeCheck.h"
-
-
-#define DblLnkLst_OffsetOf(type, field) ((intptr_t)&((type *)0)->field)
-
-#define DblLnkLst_Container(addr, type, field) \
- ((type *)((char *)addr - DblLnkLst_OffsetOf(type, field)))
-
-#define DblLnkLst_ForEach(curr, head) \
- for (curr = (head)->next; curr != (head); curr = (curr)->next)
-
-/* Safe from list element removal within loop body. */
-#define DblLnkLst_ForEachSafe(curr, nextElem, head) \
- for (curr = (head)->next, nextElem = (curr)->next; \
- curr != (head); \
- curr = nextElem, nextElem = (curr)->next)
-
-typedef struct DblLnkLst_Links {
- struct DblLnkLst_Links *prev;
- struct DblLnkLst_Links *next;
-} DblLnkLst_Links;
-
-
-/* Functions for both circular and anchored lists. --hpreg */
-
-void DblLnkLst_Init(DblLnkLst_Links *l);
-void DblLnkLst_Link(DblLnkLst_Links *l1, DblLnkLst_Links *l2);
-void DblLnkLst_Unlink(DblLnkLst_Links *l1, DblLnkLst_Links *l2);
-void DblLnkLst_Unlink1(DblLnkLst_Links *l);
-Bool DblLnkLst_IsLinked(DblLnkLst_Links const *l);
-
-/* Functions specific to anchored lists. --hpreg */
-
-void DblLnkLst_LinkFirst(DblLnkLst_Links *head, DblLnkLst_Links *l);
-void DblLnkLst_LinkLast(DblLnkLst_Links *head, DblLnkLst_Links *l);
-
-
-#endif /* _DBLLNKLST_H_ */
}
retry:
- opUsed = atomic_read(&hgfsVersionSearchRead);
+ opUsed = hgfsVersionSearchRead;
if (opUsed == HGFS_OP_SEARCH_READ_V3) {
HgfsRequest *header;
HgfsRequestSearchReadV3 *request;
if (attr->requestType == HGFS_OP_SEARCH_READ_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: Version 3 "
"not supported. Falling back to version 2.\n"));
- atomic_set(&hgfsVersionSearchRead, HGFS_OP_SEARCH_READ_V2);
+ hgfsVersionSearchRead = HGFS_OP_SEARCH_READ_V2;
goto retry;
} else if (attr->requestType == HGFS_OP_SEARCH_READ_V2) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsGetNextDirEntry: Version 2 "
"not supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionSearchRead, HGFS_OP_SEARCH_READ);
+ hgfsVersionSearchRead = HGFS_OP_SEARCH_READ;
goto retry;
}
}
retry:
- opUsed = atomic_read(&hgfsVersionSearchOpen);
+ opUsed = hgfsVersionSearchOpen;
if (opUsed == HGFS_OP_SEARCH_OPEN_V3) {
replySearch = &((HgfsReplySearchOpenV3 *)HGFS_REP_PAYLOAD_V3(req))->search;
} else {
if (opUsed == HGFS_OP_SEARCH_OPEN_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDirOpen: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionSearchOpen, HGFS_OP_SEARCH_OPEN);
+ hgfsVersionSearchOpen = HGFS_OP_SEARCH_OPEN;
goto retry;
}
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDirOpen: server "
}
retry:
- opUsed = atomic_read(&hgfsVersionSearchClose);
+ opUsed = hgfsVersionSearchClose;
if (opUsed == HGFS_OP_SEARCH_CLOSE_V3) {
HgfsRequestSearchCloseV3 *request;
HgfsRequest *header;
if (opUsed == HGFS_OP_SEARCH_CLOSE_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDirRelease: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionSearchClose, HGFS_OP_SEARCH_CLOSE);
+ hgfsVersionSearchClose = HGFS_OP_SEARCH_CLOSE;
goto retry;
}
break;
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-
-
-#ifndef _ESC_BITVECTOR_H_
-#define _ESC_BITVECTOR_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE // XXX is this true?
-#include "includeCheck.h"
-
-
-#ifdef __KERNEL__
-#include "driver-config.h"
-#include <linux/string.h>
-/* Don't include these if compiling for the Solaris or Apple kernels. */
-#elif !defined(_KERNEL) && !defined(KERNEL)
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#if defined(_KERNEL) && defined(__FreeBSD__)
-# include <sys/libkern.h>
-#elif defined(KERNEL) && defined(__APPLE__)
-# include <string.h>
-#endif
-
-#include "vm_assert.h"
-
-
-
-#define ESC_BITVECTOR_INDEX(_x) ((_x)>>5)
-#define ESC_BITVECTOR_MASK(_x) (1<<((_x)&31))
-
-#define ESC_BITVECTOR_SIZE 256 // hardwired size of the bitvector
-
-/*
- *----------------------------------------------------------------------
- *
- * EscBitVector --
- *
- * Taken from bitvector.h, but hard wired for use with the Escape
- * routines, which always need a bitvector of 256 bits, are never
- * used in the monitor, and need to work in the linux kernel. [bac]
- *
- *
- *----------------------------------------------------------------------
- */
-typedef struct EscBitVector {
- uint32 vector[ESC_BITVECTOR_SIZE/32];
-} EscBitVector;
-
-
-/*
- *----------------------------------------------------------------------
- *
- * EscBitVector_Init --
- *
- * Clear all the bits in this vector.
- *
- * Results:
- * All bits are cleared
- *
- *----------------------------------------------------------------------
- */
-static INLINE void EscBitVector_Init(EscBitVector *bv)
-{
- memset(bv, 0, sizeof(EscBitVector));
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * EscBitVector_Set, EscBitVector_Clear, EscBitVector_Test --
- *
- * basic operations
- *
- * Results:
- * insertion/deletion/presence to/from/in the set
- *
- * EscBitVector_Test returns non-zero if present, 0 otherwise
- *
- *
- *----------------------------------------------------------------------
- */
-static INLINE void EscBitVector_Set(EscBitVector *bv,int n)
-{
- ASSERT(n>=0 && n<ESC_BITVECTOR_SIZE);
-#ifdef __GNUC__
- __asm__ __volatile ( "btsl %1,%0" : "=m" (bv->vector[0]) :"Ir" (n));
-#else
- bv->vector[ESC_BITVECTOR_INDEX(n)] |= ESC_BITVECTOR_MASK(n);
-#endif
-}
-
-static INLINE void EscBitVector_Clear(EscBitVector *bv,int n)
-{
- ASSERT(n>=0 && n<ESC_BITVECTOR_SIZE);
-#ifdef __GNUC__
- __asm__ __volatile ( "btrl %1,%0" : "=m" (bv->vector[0]) :"Ir" (n));
-#else
- bv->vector[ESC_BITVECTOR_INDEX(n)] &= ~ESC_BITVECTOR_MASK(n);
-#endif
-}
-
-static INLINE int EscBitVector_Test(EscBitVector const *bv, int n)
-{
- ASSERT(n>=0 && n<ESC_BITVECTOR_SIZE);
-#ifdef __GNUC__
- {
- uint32 tmp;
- __asm__ __volatile ( "btl %2,%1\n\tsbbl %0,%0" : "=r" (tmp) : "m" (bv->vector[0]),"Ir" (n));
- return tmp;
- }
-#else
- return ((bv->vector[ESC_BITVECTOR_INDEX(n)] & ESC_BITVECTOR_MASK(n)) != 0);
-#endif
-}
-
-
-
-
-#endif /* _ESC_BITVECTOR_H_ */
-
-
* version exactly once and use the pointers later.
*/
- opUsed = atomic_read(&hgfsVersionOpen);
+ opUsed = hgfsVersionOpen;
result = HgfsPackOpenRequest(inode, file, opUsed, req);
if (result != 0) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: error packing request\n"));
if (opUsed == HGFS_OP_OPEN_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: Version 3 not "
"supported. Falling back to version 2.\n"));
- atomic_set(&hgfsVersionOpen, HGFS_OP_OPEN_V2);
+ hgfsVersionOpen = HGFS_OP_OPEN_V2;
goto retry;
}
if (opUsed == HGFS_OP_OPEN_V2) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsOpen: Version 2 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionOpen, HGFS_OP_OPEN);
+ hgfsVersionOpen = HGFS_OP_OPEN;
goto retry;
}
}
retry:
- opUsed = atomic_read(&hgfsVersionClose);
+ opUsed = hgfsVersionClose;
if (opUsed == HGFS_OP_CLOSE_V3) {
HgfsRequest *header;
HgfsRequestCloseV3 *request;
if (opUsed == HGFS_OP_CLOSE_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRelease: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionClose, HGFS_OP_CLOSE);
+ hgfsVersionClose = HGFS_OP_CLOSE;
goto retry;
}
break;
#include "compat_dcache.h"
#include "compat_fs.h"
#include "compat_kernel.h"
-#include "compat_kthread.h"
#include "compat_sched.h"
#include "compat_semaphore.h"
#include "compat_slab.h"
/* Must be included after sched.h. */
#include <linux/smp_lock.h>
-#include "bdhandler.h"
#include "filesystem.h"
+#include "transport.h"
#include "hgfsDevLinux.h"
#include "hgfsProto.h"
#include "hgfsUtil.h"
/* Synchronization primitives. */
spinlock_t hgfsBigLock = SPIN_LOCK_UNLOCKED;
-long hgfsReqThreadFlags;
-wait_queue_head_t hgfsReqThreadWait;
-struct task_struct *hgfsReqThread;
-COMPAT_KTHREAD_DECLARE_STOP_INFO();
/* Other variables. */
compat_kmem_cache *hgfsReqCache = NULL;
compat_kmem_cache *hgfsInodeCache = NULL;
-RpcOut *hgfsRpcOut = NULL;
-unsigned int hgfsIdCounter = 0;
-struct list_head hgfsReqsUnsent;
/* Global protocol version switch. */
-atomic_t hgfsVersionOpen;
-atomic_t hgfsVersionRead;
-atomic_t hgfsVersionWrite;
-atomic_t hgfsVersionClose;
-atomic_t hgfsVersionSearchOpen;
-atomic_t hgfsVersionSearchRead;
-atomic_t hgfsVersionSearchClose;
-atomic_t hgfsVersionGetattr;
-atomic_t hgfsVersionSetattr;
-atomic_t hgfsVersionCreateDir;
-atomic_t hgfsVersionDeleteFile;
-atomic_t hgfsVersionDeleteDir;
-atomic_t hgfsVersionRename;
-atomic_t hgfsVersionQueryVolumeInfo;
-atomic_t hgfsVersionCreateSymlink;
+HgfsOp hgfsVersionOpen;
+HgfsOp hgfsVersionRead;
+HgfsOp hgfsVersionWrite;
+HgfsOp hgfsVersionClose;
+HgfsOp hgfsVersionSearchOpen;
+HgfsOp hgfsVersionSearchRead;
+HgfsOp hgfsVersionSearchClose;
+HgfsOp hgfsVersionGetattr;
+HgfsOp hgfsVersionSetattr;
+HgfsOp hgfsVersionCreateDir;
+HgfsOp hgfsVersionDeleteFile;
+HgfsOp hgfsVersionDeleteDir;
+HgfsOp hgfsVersionRename;
+HgfsOp hgfsVersionQueryVolumeInfo;
+HgfsOp hgfsVersionCreateSymlink;
/* Private functions. */
static inline unsigned long HgfsComputeBlockBits(unsigned long blockSize);
static int HgfsReadSuper(struct super_block *sb,
void *rawData,
int flags);
+static void HgfsResetOps(void);
/* HGFS filesystem high-level operations. */
}
#endif
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsResetOps --
+ *
+ * Reset ops with more than one opcode back to the desired opcode.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+HgfsResetOps(void)
+{
+ hgfsVersionOpen = HGFS_OP_OPEN_V3;
+ hgfsVersionRead = HGFS_OP_READ_V3;
+ hgfsVersionWrite = HGFS_OP_WRITE_V3;
+ hgfsVersionClose = HGFS_OP_CLOSE_V3;
+ hgfsVersionSearchOpen = HGFS_OP_SEARCH_OPEN_V3;
+ hgfsVersionSearchRead = HGFS_OP_SEARCH_READ_V3;
+ hgfsVersionSearchClose = HGFS_OP_SEARCH_CLOSE_V3;
+ hgfsVersionGetattr = HGFS_OP_GETATTR_V3;
+ hgfsVersionSetattr = HGFS_OP_SETATTR_V3;
+ hgfsVersionCreateDir = HGFS_OP_CREATE_DIR_V3;
+ hgfsVersionDeleteFile = HGFS_OP_DELETE_FILE_V3;
+ hgfsVersionDeleteDir = HGFS_OP_DELETE_DIR_V3;
+ hgfsVersionRename = HGFS_OP_RENAME_V3;
+ hgfsVersionQueryVolumeInfo = HGFS_OP_QUERY_VOLUME_INFO_V3;
+ hgfsVersionCreateSymlink = HGFS_OP_CREATE_SYMLINK_V3;
+}
+
+
/*
* Public function implementations.
*/
Bool
HgfsInitFileSystem(void)
{
- Bool success = FALSE;
-
/* Initialize primitives. */
- INIT_LIST_HEAD(&hgfsReqsUnsent);
- init_waitqueue_head(&hgfsReqThreadWait);
- hgfsReqThread = NULL;
- hgfsReqThreadFlags = 0;
HgfsResetOps();
/* Setup the request slab allocator. */
NULL);
if (hgfsReqCache == NULL) {
printk(KERN_WARNING "VMware hgfs: failed to create request allocator\n");
- goto exit;
+ goto error_caches;
}
/* Setup the inode slab allocator. */
HgfsInodeCacheCtor);
if (hgfsInodeCache == NULL) {
printk(KERN_WARNING "VMware hgfs: failed to create inode allocator\n");
- goto exit;
+ goto error_caches;
}
- /* Create backdoor handler. */
- hgfsReqThread = compat_kthread_run(HgfsBdHandler, NULL, HGFS_NAME);
- if (IS_ERR(hgfsReqThread)) {
- printk(KERN_WARNING "VMware hgfs: failed to create kernel thread\n");
- goto exit;
- }
+ /* Initialize the transport. */
+ HgfsTransportInit();
/*
* Register the filesystem. This should be the last thing we do
*/
if (register_filesystem(&hgfsType)) {
printk(KERN_WARNING "VMware hgfs: failed to register filesystem\n");
- goto exit;
+ goto error_caches;
}
LOG(4, (KERN_DEBUG "VMware hgfs: Module Loaded\n"));
#ifdef HGFS_ENABLE_WRITEBACK
LOG(4, (KERN_DEBUG "VMware hgfs: writeback cache enabled\n"));
#endif
- success = TRUE;
+ return TRUE;
- exit:
-
- /* Cleanup if an error occurred. */
- if (success == FALSE) {
- if (!IS_ERR(hgfsReqThread)) {
- compat_kthread_stop(hgfsReqThread);
- }
- if (hgfsInodeCache != NULL) {
- kmem_cache_destroy(hgfsInodeCache);
- }
- if (hgfsReqCache != NULL) {
- kmem_cache_destroy(hgfsReqCache);
- }
+error_caches:
+ if (hgfsInodeCache != NULL) {
+ kmem_cache_destroy(hgfsInodeCache);
}
- return success;
+ if (hgfsReqCache != NULL) {
+ kmem_cache_destroy(hgfsReqCache);
+ }
+ return FALSE;
}
success = FALSE;
}
- /* Kill the backdoor handler thread. */
- compat_kthread_stop(hgfsReqThread);
+ /* Transport cleanup. */
+ HgfsTransportExit();
/* Destroy the inode and request slabs. */
kmem_cache_destroy(hgfsInodeCache);
retry:
- opUsed = atomic_read(&hgfsVersionGetattr);
+ opUsed = hgfsVersionGetattr;
result = HgfsPackGetattrRequest(req, dentry, allowHandleReuse, opUsed, attr);
if (result != 0) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: no attrs\n"));
if (attr->requestType == HGFS_OP_GETATTR_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: Version 3 "
"not supported. Falling back to version 2.\n"));
- atomic_set(&hgfsVersionGetattr, HGFS_OP_GETATTR_V2);
+ hgfsVersionGetattr = HGFS_OP_GETATTR_V2;
goto retry;
} else if (attr->requestType == HGFS_OP_GETATTR_V2) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: Version 2 "
"not supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionGetattr, HGFS_OP_GETATTR);
+ hgfsVersionGetattr = HGFS_OP_GETATTR;
goto retry;
}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * guest_msg_def.h --
- *
- * Second layer of the internal communication channel between guest
- * applications and vmware
- *
- */
-
-#ifndef _GUEST_MSG_DEF_H_
-#define _GUEST_MSG_DEF_H_
-
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#include "includeCheck.h"
-
-
-/* Basic request types */
-typedef enum {
- MESSAGE_TYPE_OPEN,
- MESSAGE_TYPE_SENDSIZE,
- MESSAGE_TYPE_SENDPAYLOAD,
- MESSAGE_TYPE_RECVSIZE,
- MESSAGE_TYPE_RECVPAYLOAD,
- MESSAGE_TYPE_RECVSTATUS,
- MESSAGE_TYPE_CLOSE,
-} MessageType;
-
-
-/* Reply statuses */
-/* The basic request succeeded */
-#define MESSAGE_STATUS_SUCCESS 0x0001
-/* vmware has a message available for its party */
-#define MESSAGE_STATUS_DORECV 0x0002
-/* The channel has been closed */
-#define MESSAGE_STATUS_CLOSED 0x0004
-/* vmware removed the message before the party fetched it */
-#define MESSAGE_STATUS_UNSENT 0x0008
-/* A checkpoint occurred */
-#define MESSAGE_STATUS_CPT 0x0010
-/* An underlying device is powering off */
-#define MESSAGE_STATUS_POWEROFF 0x0020
-/* vmware has detected a timeout on the channel */
-#define MESSAGE_STATUS_TIMEOUT 0x0040
-/* vmware supports high-bandwidth for sending and receiving the payload */
-#define MESSAGE_STATUS_HB 0x0080
-
-/*
- * This mask defines the status bits that the guest is allowed to set;
- * we use this to mask out all other bits when receiving the status
- * from the guest. Otherwise, the guest can manipulate VMX state by
- * setting status bits that are only supposed to be changed by the
- * VMX. See bug 45385.
- */
-#define MESSAGE_STATUS_GUEST_MASK MESSAGE_STATUS_SUCCESS
-
-/*
- * Max number of channels.
- * Unfortunately this has to be public because the monitor part
- * of the backdoor needs it for its trivial-case optimization. [greg]
- */
-#define GUESTMSG_MAX_CHANNEL 8
-
-/* Flags to open a channel. --hpreg */
-#define GUESTMSG_FLAG_COOKIE 0x80000000
-#define GUESTMSG_FLAG_ALL GUESTMSG_FLAG_COOKIE
-
-/*
- * Maximum size of incoming message. This is to prevent denial of host service
- * attacks from guest applications.
- */
-#define GUESTMSG_MAX_IN_SIZE (64 * 1024)
-
-#endif /* _GUEST_MSG_DEF_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef _HGFS_BD_H_
-# define _HGFS_BD_H_
-
-/*
- * hgfsBd.h --
- *
- * Backdoor calls used by hgfs clients.
- */
-
-#include "rpcout.h"
-
-char *HgfsBd_GetBuf(void);
-
-char *HgfsBd_GetLargeBuf(void);
-
-void HgfsBd_PutBuf(char *);
-
-RpcOut *HgfsBd_GetChannel(void);
-
-Bool HgfsBd_CloseChannel(RpcOut *out);
-
-int HgfsBd_Dispatch(RpcOut *out,
- char *packetIn,
- size_t *packetSize,
- char const **packetOut);
-
-Bool HgfsBd_Enabled(RpcOut *out,
- char *requestPacket);
-
-Bool HgfsBd_OpenBackdoor(RpcOut **out);
-
-Bool HgfsBd_CloseBackdoor(RpcOut **out);
-
-#endif // _HGFS_BD_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * hgfsDev.h --
- *
- * Header for code shared between the hgfs linux kernel module driver
- * and the pserver.
- */
-
-#ifndef _HGFS_DEV_H_
-#define _HGFS_DEV_H_
-
-#include "vm_basic_types.h"
-#include "hgfs.h"
-
-#define HGFS_NAME "vmhgfs" // Name of FS (e.g. "mount -t vmhgfs")
-#define HGFS_DEVICE_NAME "dev" // Name of our device under /proc/fs/HGFS_NAME/
-#define HGFS_SUPER_MAGIC 0xbacbacbc // Superblock magic number
-#define HGFS_PROTOCOL_VERSION 1 // Incremented when something changes
-#define HGFS_DEFAULT_TTL 1 // Default TTL for dentries
-
-/*
- * Mount information, passed from pserver process to kernel
- * at mount time.
- *
- * XXX: I'm hijacking this struct. In the future, when the Solaris HGFS driver
- * loses its pserver, the struct will be used by /sbin/mount.vmhgfs solely.
- * As is, it is also used by the Solaris pserver.
- */
-typedef struct HgfsMountInfo {
- uint32 magicNumber; // hgfs magic number
- uint32 version; // protocol version
- uint32 fd; // file descriptor of client file
-#ifndef sun
- uid_t uid; // desired owner of files
- Bool uidSet; // is the owner actually set?
- gid_t gid; // desired group of files
- Bool gidSet; // is the group actually set?
- unsigned short fmask; // desired file mask
- unsigned short dmask; // desired directory mask
- uint32 ttl; // number of seconds before revalidating dentries
- const char *shareNameHost; // must be ".host"
- const char *shareNameDir; // desired share name for mounting
-#endif
-} HgfsMountInfo;
-
-#endif //ifndef _HGFS_DEV_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * hgfsEscape.h --
- *
- * Escape and unescape filenames that are not legal on a particular
- * platform.
- *
- */
-
-#ifndef __HGFS_ESCAPE_H__
-#define __HGFS_ESCAPE_H__
-
-int HgfsEscape_GetSize(char const *bufIn, // IN
- uint32 sizeIn); // IN
-int HgfsEscape_Do(char const *bufIn, // IN
- uint32 sizeIn, // IN
- uint32 sizeBufOut, // IN
- char *bufOut); // OUT
-
-int HgfsEscape_Undo(char *bufIn, // IN
- uint32 sizeIn); // IN
-
-#endif // __HGFS_ESCAPE_H__
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-
-/*
- * hgfsProto.h --
- *
- * Header file for data types and message formats used in the
- * Host/Guest File System (hgfs) protocol.
- */
-
-
-#ifndef _HGFS_PROTO_H_
-# define _HGFS_PROTO_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-#include "hgfs.h"
-
-/*
- * Handle used by the server to identify files and searches. Used
- * by the driver to match server replies with pending requests.
- */
-
-typedef uint32 HgfsHandle;
-#define HGFS_INVALID_HANDLE ((HgfsHandle)~((HgfsHandle)0))
-
-/*
- * Opcodes for server operations.
- *
- * Changing the ordering of this enum will break the protocol; new ops
- * should be added at the end (but before HGFS_OP_MAX).
- */
-
-typedef enum {
- HGFS_OP_OPEN, /* Open file */
- HGFS_OP_READ, /* Read from file */
- HGFS_OP_WRITE, /* Write to file */
- HGFS_OP_CLOSE, /* Close file */
- HGFS_OP_SEARCH_OPEN, /* Start new search */
- HGFS_OP_SEARCH_READ, /* Get next search response */
- HGFS_OP_SEARCH_CLOSE, /* End a search */
- HGFS_OP_GETATTR, /* Get file attributes */
- HGFS_OP_SETATTR, /* Set file attributes */
- HGFS_OP_CREATE_DIR, /* Create new directory */
- HGFS_OP_DELETE_FILE, /* Delete a file */
- HGFS_OP_DELETE_DIR, /* Delete a directory */
- HGFS_OP_RENAME, /* Rename a file or directory */
- HGFS_OP_QUERY_VOLUME_INFO, /* Query volume information */
-
- /*
- * The following operations are only available in version 2 of the hgfs
- * protocol. The corresponding version 1 opcodes above are deprecated.
- */
-
- HGFS_OP_OPEN_V2, /* Open file */
- HGFS_OP_GETATTR_V2, /* Get file attributes */
- HGFS_OP_SETATTR_V2, /* Set file attributes */
- HGFS_OP_SEARCH_READ_V2, /* Get next search response */
- HGFS_OP_CREATE_SYMLINK, /* Create a symlink */
- HGFS_OP_SERVER_LOCK_CHANGE, /* Change the oplock on a file */
- HGFS_OP_CREATE_DIR_V2, /* Create a directory */
- HGFS_OP_DELETE_FILE_V2, /* Delete a file */
- HGFS_OP_DELETE_DIR_V2, /* Delete a directory */
- HGFS_OP_RENAME_V2, /* Rename a file or directory */
-
- /*
- * Operations for version 3, deprecating version 2 operations.
- */
-
- HGFS_OP_OPEN_V3, /* Open file */
- HGFS_OP_READ_V3, /* Read from file */
- HGFS_OP_WRITE_V3, /* Write to file */
- HGFS_OP_CLOSE_V3, /* Close file */
- HGFS_OP_SEARCH_OPEN_V3, /* Start new search */
- HGFS_OP_SEARCH_READ_V3, /* Start new search */
- HGFS_OP_SEARCH_CLOSE_V3, /* End a search */
- HGFS_OP_GETATTR_V3, /* Get file attributes */
- HGFS_OP_SETATTR_V3, /* Set file attributes */
- HGFS_OP_CREATE_DIR_V3, /* Create new directory */
- HGFS_OP_DELETE_FILE_V3, /* Delete a file */
- HGFS_OP_DELETE_DIR_V3, /* Delete a directory */
- HGFS_OP_RENAME_V3, /* Rename a file or directory */
- HGFS_OP_QUERY_VOLUME_INFO_V3, /* Query volume information */
- HGFS_OP_CREATE_SYMLINK_V3, /* Create a symlink */
- HGFS_OP_SERVER_LOCK_CHANGE_V3, /* Change the oplock on a file */
-
- HGFS_OP_MAX, /* Dummy op, must be last in enum */
-} HgfsOp;
-
-
-/* HGFS protocol versions. */
-#define HGFS_VERSION_OLD (1 << 0)
-#define HGFS_VERSION_3 (1 << 1)
-
-/* XXX: Needs change when VMCI is supported. */
-#define HGFS_REQ_PAYLOAD_SIZE_V3(hgfsReq) (sizeof *hgfsReq + sizeof(HgfsRequest))
-#define HGFS_REP_PAYLOAD_SIZE_V3(hgfsRep) (sizeof *hgfsRep + sizeof(HgfsReply))
-
-/* XXX: Needs change when VMCI is supported. */
-#define HGFS_REQ_GET_PAYLOAD_V3(hgfsReq) ((char *)(hgfsReq) + sizeof(HgfsRequest))
-#define HGFS_REP_GET_PAYLOAD_V3(hgfsRep) ((char *)(hgfsRep) + sizeof(HgfsReply))
-
-
-/*
- * File types, used in HgfsAttr. We support regular files,
- * directories, and symlinks.
- *
- * Changing the order of this enum will break the protocol; new types
- * should be added at the end.
- */
-
-typedef enum {
- HGFS_FILE_TYPE_REGULAR,
- HGFS_FILE_TYPE_DIRECTORY,
- HGFS_FILE_TYPE_SYMLINK,
-} HgfsFileType;
-
-
-/*
- * Open flags.
- *
- * Changing the order of this enum will break stuff. Do not add any flags to
- * this enum: it has been frozen and all new flags should be added to
- * HgfsOpenMode. This was done because HgfsOpenMode could still be converted
- * to a bitmask (so that it's easier to add flags to) whereas this enum was
- * already too large.
- */
-
-typedef enum { // File doesn't exist File exists
- HGFS_OPEN, // error
- HGFS_OPEN_EMPTY, // error size = 0
- HGFS_OPEN_CREATE, // create
- HGFS_OPEN_CREATE_SAFE, // create error
- HGFS_OPEN_CREATE_EMPTY, // create size = 0
-} HgfsOpenFlags;
-
-
-/*
- * Write flags.
- */
-
-typedef uint8 HgfsWriteFlags;
-
-#define HGFS_WRITE_APPEND 1
-
-
-/*
- * Permissions bits.
- *
- * These are intentionally similar to Unix permissions bits, and we
- * convert to/from Unix permissions using simple shift operations, so
- * don't change these or you will break things.
- */
-
-typedef uint8 HgfsPermissions;
-
-#define HGFS_PERM_READ 4
-#define HGFS_PERM_WRITE 2
-#define HGFS_PERM_EXEC 1
-
-/*
- * Access mode bits.
- *
- * Different operating systems have different set of file access mode.
- * Here are constants that are rich enough to describe all access modes in an OS
- * independent way.
- */
-
-typedef uint32 HgfsAccessMode;
-/*
- * Generic access rights control coarse grain access for the file.
- * A particular generic rigth can be expanded into different set of specific rights
- * on different OS.
- */
-
-/*
- * HGFS_MODE_GENERIC_READ means ability to read file data and read various file
- * attributes and properties.
- */
-#define HGFS_MODE_GENERIC_READ (1 << 0)
-/*
- * HGFS_MODE_GENERIC_WRITE means ability to write file data and updaate various file
- * attributes and properties.
- */
-#define HGFS_MODE_GENERIC_WRITE (1 << 1)
-/*
- * HGFS_MODE_GENERIC_EXECUE means ability to execute file. For network redirectors
- * ability to execute usualy implies ability to read data; for local file systems
- * HGFS_MODE_GENERIC_EXECUTE does not imply ability to read data.
- */
-#define HGFS_MODE_GENERIC_EXECUTE (1 << 2)
-
-/* Specific rights define fine grain access modes. */
-#define HGFS_MODE_READ_DATA (1 << 3) // Ability to read file data
-#define HGFS_MODE_WRITE_DATA (1 << 4) // Ability to writge file data
-#define HGFS_MODE_APPEND_DATA (1 << 5) // Appending data to the end of file
-#define HGFS_MODE_DELETE (1 << 6) // Ability to delete the file
-#define HGFS_MODE_TRAVERSE_DIRECTORY (1 << 7) // Ability to access files in a directory
-#define HGFS_MODE_LIST_DIRECTORY (1 << 8) // Ability to list file names
-#define HGFS_MODE_ADD_SUBDIRECTORY (1 << 9) // Ability to create a new subdirectory
-#define HGFS_MODE_ADD_FILE (1 << 10) // Ability to create a new file
-#define HGFS_MODE_DELETE_CHILD (1 << 11) // Ability to delete file/subdirectory
-#define HGFS_MODE_READ_ATTRIBUTES (1 << 12) // Ability to read attributes
-#define HGFS_MODE_WRITE_ATTRIBUTES (1 << 13) // Ability to write attributes
-#define HGFS_MODE_READ_EXTATTRIBUTES (1 << 14) // Ability to read extended attributes
-#define HGFS_MODE_WRITE_EXTATTRIBUTES (1 << 15) // Ability to write extended attributes
-#define HGFS_MODE_READ_SECURITY (1 << 16) // Ability to read permissions/ACLs/owner
-#define HGFS_MODE_WRITE_SECURITY (1 << 17) // Ability to change permissions/ACLs
-#define HGFS_MODE_TAKE_OWNERSHIP (1 << 18) // Ability to change file owner/group
-
-/*
- * Server-side locking (oplocks and leases).
- *
- * The client can ask the server to acquire opportunistic locking/leasing
- * from the host FS on its behalf. This is communicated as part of an open request.
- *
- * HGFS_LOCK_OPPORTUNISTIC means that the client trusts the server
- * to decide what kind of locking to request from the host FS.
- * All other values tell the server explicitly the type of lock to
- * request.
- *
- * The server will attempt to acquire the desired lock and will notify the client
- * which type of lock was acquired as part of the reply to the open request.
- * Note that HGFS_LOCK_OPPORTUNISTIC should not be specified as the type of
- * lock acquired by the server, since HGFS_LOCK_OPPORTUNISTIC is not an
- * actual lock.
- */
-
-typedef enum {
- HGFS_LOCK_NONE,
- HGFS_LOCK_OPPORTUNISTIC,
- HGFS_LOCK_EXCLUSIVE,
- HGFS_LOCK_SHARED,
-} HgfsServerLock;
-
-
-/*
- * Flags to indicate in a setattr request which fields should be
- * updated. Deprecated.
- */
-
-typedef uint8 HgfsAttrChanges;
-
-#define HGFS_ATTR_SIZE (1 << 0)
-#define HGFS_ATTR_CREATE_TIME (1 << 1)
-#define HGFS_ATTR_ACCESS_TIME (1 << 2)
-#define HGFS_ATTR_WRITE_TIME (1 << 3)
-#define HGFS_ATTR_CHANGE_TIME (1 << 4)
-#define HGFS_ATTR_PERMISSIONS (1 << 5)
-#define HGFS_ATTR_ACCESS_TIME_SET (1 << 6)
-#define HGFS_ATTR_WRITE_TIME_SET (1 << 7)
-
-
-/*
- * Hints to indicate in a getattr or setattr which attributes
- * are valid for the request.
- * For setattr only, attributes should be set by host even if
- * no valid values are specified by the guest.
- */
-
-typedef uint64 HgfsAttrHint;
-
-#define HGFS_ATTR_HINT_SET_ACCESS_TIME (1 << 0)
-#define HGFS_ATTR_HINT_SET_WRITE_TIME (1 << 1)
-#define HGFS_ATTR_HINT_USE_FILE_DESC (1 << 2)
-
-/*
- * Hint to determine using a name or a handle to determine
- * what to delete.
- */
-
-typedef uint64 HgfsDeleteHint;
-
-#define HGFS_DELETE_HINT_USE_FILE_DESC (1 << 0)
-
-/*
- * Hint to determine using a name or a handle to determine
- * what to renames.
- */
-
-typedef uint64 HgfsRenameHint;
-
-#define HGFS_RENAME_HINT_USE_SRCFILE_DESC (1 << 0)
-#define HGFS_RENAME_HINT_USE_TARGETFILE_DESC (1 << 1)
-#define HGFS_RENAME_HINT_NO_REPLACE_EXISTING (1 << 2)
-#define HGFS_RENAME_HINT_NO_COPY_ALLOWED (1 << 3)
-
-/*
- * File attributes.
- *
- * The four time fields below are in Windows NT format, which is in
- * units of 100ns since Jan 1, 1601, UTC.
- */
-
-/*
- * Version 1 attributes. Deprecated.
- * Version 2 should be using HgfsAttrV2.
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsAttr {
- HgfsFileType type; /* File type */
- uint64 size; /* File size (in bytes) */
- uint64 creationTime; /* Creation time. Ignored by POSIX */
- uint64 accessTime; /* Time of last access */
- uint64 writeTime; /* Time of last write */
- uint64 attrChangeTime; /* Time file attributess were last
- * changed. Ignored by Windows */
- HgfsPermissions permissions; /* Permissions bits */
-}
-#include "vmware_pack_end.h"
-HgfsAttr;
-
-
-/* Various flags and Windows attributes. */
-
-typedef uint64 HgfsAttrFlags;
-
-#define HGFS_ATTR_HIDDEN (1 << 0)
-#define HGFS_ATTR_SYSTEM (1 << 1)
-#define HGFS_ATTR_ARCHIVE (1 << 2)
-#define HGFS_ATTR_HIDDEN_FORCED (1 << 3)
-
-
-/*
- * Specifies which open request fields contain
- * valid values.
- */
-
-typedef uint64 HgfsOpenValid;
-
-#define HGFS_OPEN_VALID_NONE 0
-#define HGFS_OPEN_VALID_MODE (1 << 0)
-#define HGFS_OPEN_VALID_FLAGS (1 << 1)
-#define HGFS_OPEN_VALID_SPECIAL_PERMS (1 << 2)
-#define HGFS_OPEN_VALID_OWNER_PERMS (1 << 3)
-#define HGFS_OPEN_VALID_GROUP_PERMS (1 << 4)
-#define HGFS_OPEN_VALID_OTHER_PERMS (1 << 5)
-#define HGFS_OPEN_VALID_FILE_ATTR (1 << 6)
-#define HGFS_OPEN_VALID_ALLOCATION_SIZE (1 << 7)
-#define HGFS_OPEN_VALID_DESIRED_ACCESS (1 << 8)
-#define HGFS_OPEN_VALID_SHARE_ACCESS (1 << 9)
-#define HGFS_OPEN_VALID_SERVER_LOCK (1 << 10)
-#define HGFS_OPEN_VALID_FILE_NAME (1 << 11)
-
-
-/*
- * Specifies which attribute fields contain
- * valid values.
- */
-
-typedef uint64 HgfsAttrValid;
-
-#define HGFS_ATTR_VALID_NONE 0
-#define HGFS_ATTR_VALID_TYPE (1 << 0)
-#define HGFS_ATTR_VALID_SIZE (1 << 1)
-#define HGFS_ATTR_VALID_CREATE_TIME (1 << 2)
-#define HGFS_ATTR_VALID_ACCESS_TIME (1 << 3)
-#define HGFS_ATTR_VALID_WRITE_TIME (1 << 4)
-#define HGFS_ATTR_VALID_CHANGE_TIME (1 << 5)
-#define HGFS_ATTR_VALID_SPECIAL_PERMS (1 << 6)
-#define HGFS_ATTR_VALID_OWNER_PERMS (1 << 7)
-#define HGFS_ATTR_VALID_GROUP_PERMS (1 << 8)
-#define HGFS_ATTR_VALID_OTHER_PERMS (1 << 9)
-#define HGFS_ATTR_VALID_FLAGS (1 << 10)
-#define HGFS_ATTR_VALID_ALLOCATION_SIZE (1 << 11)
-#define HGFS_ATTR_VALID_USERID (1 << 12)
-#define HGFS_ATTR_VALID_GROUPID (1 << 13)
-#define HGFS_ATTR_VALID_FILEID (1 << 14)
-#define HGFS_ATTR_VALID_VOLID (1 << 15)
-/*
- * Add our file and volume identifiers.
- * NOTE: On Windows hosts, the file identifier is not guaranteed to be valid
- * particularly with FAT. A defrag operation could cause it to change.
- * Therefore, to not confuse older clients, and non-Windows
- * clients we have added a separate flag.
- * The Windows client will check for both flags for the
- * file ID, and return the information to the guest application.
- * However, it will use the ID internally, when it has an open
- * handle on the server.
- * Non-Windows clients need the file ID to be always guaranteed,
- * which is to say, that the ID remains constant over the course of the
- * file's lifetime, and will use the HGFS_ATTR_VALID_FILEID flag
- * only to determine if the ID is valid.
- */
-#define HGFS_ATTR_VALID_NON_STATIC_FILEID (1 << 16)
-/*
- * File permissions that are in effect for the user which runs HGFS server.
- * Client needs to know effective permissions in order to implement access(2).
- * Client can't derive it from group/owner/other permissions because of two resaons:
- * 1. It does not know user/group id of the user which runs HGFS server
- * 2. Effective permissions account for additional restrictions that may be imposed
- * by host file system, for example by ACL.
- */
-#define HGFS_ATTR_VALID_EFFECTIVE_PERMS (1 << 17)
-
-
-/*
- * Specifies which create dir request fields contain
- * valid values.
- */
-
-typedef uint64 HgfsCreateDirValid;
-
-#define HGFS_CREATE_DIR_VALID_NONE 0
-#define HGFS_CREATE_DIR_VALID_SPECIAL_PERMS (1 << 0)
-#define HGFS_CREATE_DIR_VALID_OWNER_PERMS (1 << 1)
-#define HGFS_CREATE_DIR_VALID_GROUP_PERMS (1 << 2)
-#define HGFS_CREATE_DIR_VALID_OTHER_PERMS (1 << 3)
-#define HGFS_CREATE_DIR_VALID_FILE_NAME (1 << 4)
-
-/*
- * Version 2 of HgfsAttr
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsAttrV2 {
- HgfsAttrValid mask; /* A bit mask to determine valid attribute fields */
- HgfsFileType type; /* File type */
- uint64 size; /* File size (in bytes) */
- uint64 creationTime; /* Creation time. Ignored by POSIX */
- uint64 accessTime; /* Time of last access */
- uint64 writeTime; /* Time of last write */
- uint64 attrChangeTime; /* Time file attributes were last
- * changed. Ignored by Windows */
- HgfsPermissions specialPerms; /* Special permissions bits (suid, etc.).
- * Ignored by Windows */
- HgfsPermissions ownerPerms; /* Owner permissions bits */
- HgfsPermissions groupPerms; /* Group permissions bits. Ignored by
- * Windows */
- HgfsPermissions otherPerms; /* Other permissions bits. Ignored by
- * Windows */
- HgfsAttrFlags flags; /* Various flags and Windows 'attributes' */
- uint64 allocationSize; /* Actual size of file on disk */
- uint32 userId; /* User identifier, ignored by Windows */
- uint32 groupId; /* group identifier, ignored by Windows */
- uint64 hostFileId; /* File Id of the file on host: inode_t on Linux */
- uint32 volumeId; /* volume identifier, non-zero is valid. */
- uint32 effectivePerms; /* Permissions in effect for the user on the host. */
- uint64 reserved2; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsAttrV2;
-
-
-/*
- * Cross-platform filename representation
- *
- * Cross-platform (CP) names are represented by a string with each
- * path component separated by NULs, and terminated with a final NUL,
- * but with no leading path separator.
- *
- * For example, the representations of a POSIX and Windows name
- * are as follows, with "0" meaning NUL.
- *
- * Original name Cross-platform name
- * -----------------------------------------------------
- * "/home/bac/temp" -> "home0bac0temp0"
- * "C:\temp\file.txt" -> "C0temp0file.txt0"
- *
- * Note that as in the example above, Windows should strip the colon
- * off of drive letters as part of the conversion. Aside from that,
- * all characters in each path component should be left unescaped and
- * unmodified. Each OS is responsible for escaping any characters that
- * are not legal in its filenames when converting FROM the CP name
- * format, and unescaping them when converting TO the CP name format.
- *
- * In some requests (OPEN, GETATTR, SETATTR, DELETE, CREATE_DIR) the
- * CP name is used to represent a particular file, but it is also used
- * to represent a search pattern for looking up files using
- * SEARCH_OPEN.
- *
- * In the current HGFS server implementation, each request has a minimum packet
- * size that must be met for it to be considered valid. This minimum is simply
- * the sizeof the particular request, which includes the solitary byte from the
- * HgfsFileName struct. For these particular requests, clients add an extra
- * byte to their payload size, without that byte being present anywhere.
- *
- * It isn't clear that this behavior is correct, but the end result is that
- * neither end malfunctions, as an extra byte gets sent by the client and is
- * ignored by the server. Unfortunately, it cannot be easily fixed. The
- * server's minimum packet size can be changed, but the client should continue
- * to send an extra byte, otherwise older servers with a slightly longer
- * minimum packet size may consider the new client's packets to be too short.
- *
- * UTF-8 representation
- * --------------------
- * XXX: It is expected that file names in the HGFS protocol will be a valid UTF-8
- * encoding.
- * See RFC 3629 (http://tools.ietf.org/html/rfc3629)
- *
- * Unicode Format
- * --------------
- * HGFS protocol requests that contain file names as in the structure below,
- * should contain unicode normal form C (precomposed see explanation below)
- * characters therefore hosts such as Mac OS X which
- * use HFS+ and unicode form D should convert names before
- * processing or sending HGFS requests.
- *
- * Precomposed (normal form C) versus Decomposed (normal form D)
- * -------------------------------------------------------------
- * Certain Unicode characters can be encoded in more than one way.
- * For example, an (A acute) can be encoded either precomposed,
- * as U+00C1 (LATIN CAPITAL LETTER A WITH ACUTE), or decomposed,
- * as U+0041 U+0301 (LATIN CAPITAL LETTER A followed by a COMBINING ACUTE ACCENT).
- * Precomposed characters are more common in the Windows world,
- * whereas decomposed characters are more common on the Mac.
- *
- * See UAX 15 (http://unicode.org/reports/tr15/)
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsFileName {
- uint32 length; /* Does NOT include terminating NUL */
- char name[1];
-}
-#include "vmware_pack_end.h"
-HgfsFileName;
-
-
-/*
- * Case-sensitiviy flags are only used when any lookup is
- * involved on the server side.
- */
-
-typedef enum {
- HGFS_FILE_NAME_DEFAULT_CASE,
- HGFS_FILE_NAME_CASE_SENSITIVE,
- HGFS_FILE_NAME_CASE_INSENSITIVE,
-} HgfsCaseType;
-
-
-/*
- * HgfsFileNameV3 - new header to incorporate case-sensitivity flags along with
- * Hgfs file handle.
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsFileNameV3 {
- uint32 length; /* Does NOT include terminating NUL */
- uint32 flags; /* Flags described below. */
- HgfsCaseType caseType; /* Case-sensitivity type. */
- HgfsHandle fid;
- char name[1];
-}
-#include "vmware_pack_end.h"
-HgfsFileNameV3;
-
-
-/*
- * HgfsFileNameV3 flags. Case-sensitiviy flags are only used when any lookup is
- * involved on the server side.
- */
-#define HGFS_FILE_NAME_USE_FILE_DESC (1 << 0) /* Case type ignored if set. */
-
-
-/*
- * Request/reply structs. These are the first members of all
- * operation request and reply messages, respectively.
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequest {
- HgfsHandle id; /* Opaque request ID used by the requestor */
- HgfsOp op;
-}
-#include "vmware_pack_end.h"
-HgfsRequest;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReply {
- HgfsHandle id; /* Opaque request ID used by the requestor */
- HgfsStatus status;
-}
-#include "vmware_pack_end.h"
-HgfsReply;
-
-
-/*
- * Messages for our file operations.
- */
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestOpen {
- HgfsRequest header;
- HgfsOpenMode mode; /* Which type of access is requested */
- HgfsOpenFlags flags; /* Which flags to open the file with */
- HgfsPermissions permissions; /* Which permissions to *create* a new file with */
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestOpen;
-
-
-/* Version 2 of HgfsRequestOpen */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestOpenV2 {
- HgfsRequest header;
- HgfsOpenValid mask; /* Bitmask that specified which fields are valid. */
- HgfsOpenMode mode; /* Which type of access requested. See desiredAccess */
- HgfsOpenFlags flags; /* Which flags to open the file with */
- HgfsPermissions specialPerms; /* Desired 'special' permissions for file creation */
- HgfsPermissions ownerPerms; /* Desired 'owner' permissions for file creation */
- HgfsPermissions groupPerms; /* Desired 'group' permissions for file creation */
- HgfsPermissions otherPerms; /* Desired 'other' permissions for file creation */
- HgfsAttrFlags attr; /* Attributes, if any, for file creation */
- uint64 allocationSize; /* How much space to pre-allocate during creation */
- uint32 desiredAccess; /* Extended support for windows access modes */
- uint32 shareAccess; /* Windows only, share access modes */
- HgfsServerLock desiredLock; /* The type of lock desired by the client */
- uint64 reserved1; /* Reserved for future use */
- uint64 reserved2; /* Reserved for future use */
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestOpenV2;
-
-
-/* Version 3 of HgfsRequestOpen */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestOpenV3 {
- HgfsOpenValid mask; /* Bitmask that specified which fields are valid. */
- HgfsOpenMode mode; /* Which type of access requested. See desiredAccess */
- HgfsOpenFlags flags; /* Which flags to open the file with */
- HgfsPermissions specialPerms; /* Desired 'special' permissions for file creation */
- HgfsPermissions ownerPerms; /* Desired 'owner' permissions for file creation */
- HgfsPermissions groupPerms; /* Desired 'group' permissions for file creation */
- HgfsPermissions otherPerms; /* Desired 'other' permissions for file creation */
- HgfsAttrFlags attr; /* Attributes, if any, for file creation */
- uint64 allocationSize; /* How much space to pre-allocate during creation */
- uint32 desiredAccess; /* Extended support for windows access modes */
- uint32 shareAccess; /* Windows only, share access modes */
- HgfsServerLock desiredLock; /* The type of lock desired by the client */
- uint64 reserved1; /* Reserved for future use */
- uint64 reserved2; /* Reserved for future use */
- HgfsFileNameV3 fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestOpenV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyOpen {
- HgfsReply header;
- HgfsHandle file; /* Opaque file ID used by the server */
-}
-#include "vmware_pack_end.h"
-HgfsReplyOpen;
-
-
-/* Version 2 of HgfsReplyOpen */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyOpenV2 {
- HgfsReply header;
- HgfsHandle file; /* Opaque file ID used by the server */
- HgfsServerLock acquiredLock; /* The type of lock acquired by the server */
-}
-#include "vmware_pack_end.h"
-HgfsReplyOpenV2;
-
-
-/* Version 3 of HgfsReplyOpen */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyOpenV3 {
- HgfsHandle file; /* Opaque file ID used by the server */
- HgfsServerLock acquiredLock; /* The type of lock acquired by the server */
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplyOpenV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestRead {
- HgfsRequest header;
- HgfsHandle file; /* Opaque file ID used by the server */
- uint64 offset;
- uint32 requiredSize;
-}
-#include "vmware_pack_end.h"
-HgfsRequestRead;
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyRead {
- HgfsReply header;
- uint32 actualSize;
- char payload[1];
-}
-#include "vmware_pack_end.h"
-HgfsReplyRead;
-
-
-/*
- * Version 3 of HgfsRequestRead.
- * Server must support HGFS_LARGE_PACKET_MAX to implement this op.
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestReadV3 {
- HgfsHandle file; /* Opaque file ID used by the server */
- uint64 offset;
- uint32 requiredSize;
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsRequestReadV3;
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyReadV3 {
- uint32 actualSize;
- uint64 reserved; /* Reserved for future use */
- char payload[1];
-}
-#include "vmware_pack_end.h"
-HgfsReplyReadV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestWrite {
- HgfsRequest header;
- HgfsHandle file; /* Opaque file ID used by the server */
- HgfsWriteFlags flags;
- uint64 offset;
- uint32 requiredSize;
- char payload[1];
-}
-#include "vmware_pack_end.h"
-HgfsRequestWrite;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyWrite {
- HgfsReply header;
- uint32 actualSize;
-}
-#include "vmware_pack_end.h"
-HgfsReplyWrite;
-
-/*
- * Version 3 of HgfsRequestWrite.
- * Server must support HGFS_LARGE_PACKET_MAX to implement this op.
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestWriteV3 {
- HgfsHandle file; /* Opaque file ID used by the server */
- HgfsWriteFlags flags;
- uint64 offset;
- uint32 requiredSize;
- uint64 reserved; /* Reserved for future use */
- char payload[1];
-}
-#include "vmware_pack_end.h"
-HgfsRequestWriteV3;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyWriteV3 {
- uint32 actualSize;
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplyWriteV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestClose {
- HgfsRequest header;
- HgfsHandle file; /* Opaque file ID used by the server */
-}
-#include "vmware_pack_end.h"
-HgfsRequestClose;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyClose {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplyClose;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestCloseV3 {
- HgfsHandle file; /* Opaque file ID used by the server */
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsRequestCloseV3;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyCloseV3 {
- uint64 reserved;
-}
-#include "vmware_pack_end.h"
-HgfsReplyCloseV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSearchOpen {
- HgfsRequest header;
- HgfsFileName dirName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestSearchOpen;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSearchOpenV3 {
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 dirName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestSearchOpenV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySearchOpen {
- HgfsReply header;
- HgfsHandle search; /* Opaque search ID used by the server */
-}
-#include "vmware_pack_end.h"
-HgfsReplySearchOpen;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySearchOpenV3 {
- HgfsHandle search; /* Opaque search ID used by the server */
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplySearchOpenV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSearchRead {
- HgfsRequest header;
- HgfsHandle search; /* Opaque search ID used by the server */
- uint32 offset; /* The first result is offset 0 */
-}
-#include "vmware_pack_end.h"
-HgfsRequestSearchRead;
-
-
-/* Version 2 of HgfsRequestSearchRead */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSearchReadV2 {
- HgfsRequest header;
- HgfsHandle search; /* Opaque search ID used by the server */
- uint32 offset; /* The first result is offset 0 */
-}
-#include "vmware_pack_end.h"
-HgfsRequestSearchReadV2;
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSearchReadV3 {
- HgfsHandle search; /* Opaque search ID used by the server */
- uint32 offset; /* The first result is offset 0 */
- uint32 flags; /* Reserved for reading multiple directory entries. */
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsRequestSearchReadV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySearchRead {
- HgfsReply header;
- HgfsAttr attr;
- HgfsFileName fileName;
- /* fileName.length = 0 means "no entry at this offset" */
-}
-#include "vmware_pack_end.h"
-HgfsReplySearchRead;
-
-
-/* Version 2 of HgfsReplySearchRead */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySearchReadV2 {
- HgfsReply header;
- HgfsAttrV2 attr;
-
- /*
- * fileName.length = 0 means "no entry at this offset"
- * If the file is a symlink (as specified in attr)
- * this name is the name of the symlink, not the target.
- */
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsReplySearchReadV2;
-
-
-/* Directory entry structure. */
-
-typedef struct HgfsDirEntry {
- uint32 nextEntry;
- HgfsAttrV2 attr;
-
- /*
- * fileName.length = 0 means "no entry at this offset"
- * If the file is a symlink (as specified in attr)
- * this name is the name of the symlink, not the target.
- */
- HgfsFileNameV3 fileName;
-} HgfsDirEntry;
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySearchReadV3 {
- uint64 count; /* Number of directory entries. */
- uint64 reserved; /* Reserved for future use. */
- char payload[1]; /* Directory entries. */
-}
-#include "vmware_pack_end.h"
-HgfsReplySearchReadV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSearchClose {
- HgfsRequest header;
- HgfsHandle search; /* Opaque search ID used by the server */
-}
-#include "vmware_pack_end.h"
-HgfsRequestSearchClose;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySearchClose {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplySearchClose;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSearchCloseV3 {
- HgfsHandle search; /* Opaque search ID used by the server */
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsRequestSearchCloseV3;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySearchCloseV3 {
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplySearchCloseV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestGetattr {
- HgfsRequest header;
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestGetattr;
-
-
-/* Version 2 of HgfsRequestGetattr */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestGetattrV2 {
- HgfsRequest header;
- HgfsAttrHint hints; /* Flags for file handle valid. */
- HgfsHandle file; /* Opaque file ID used by the server. */
- HgfsFileName fileName; /* Filename used when file handle invalid. */
-}
-#include "vmware_pack_end.h"
-HgfsRequestGetattrV2;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestGetattrV3 {
- HgfsAttrHint hints; /* Flags for file handle valid. */
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 fileName; /* Filename used when file handle invalid. */
-}
-#include "vmware_pack_end.h"
-HgfsRequestGetattrV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyGetattr {
- HgfsReply header;
- HgfsAttr attr;
-}
-#include "vmware_pack_end.h"
-HgfsReplyGetattr;
-
-
-/* Version 2 of HgfsReplyGetattr */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyGetattrV2 {
- HgfsReply header;
- HgfsAttrV2 attr;
-
- /*
- * If the file is a symlink, as specified in attr.type, then this is
- * the target for the symlink. If the file is not a symlink, this should
- * be ignored.
- *
- * This filename is in "CPNameLite" format. See CPNameLite.c for details.
- */
- HgfsFileName symlinkTarget;
-}
-#include "vmware_pack_end.h"
-HgfsReplyGetattrV2;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyGetattrV3 {
- HgfsAttrV2 attr;
-
- /*
- * If the file is a symlink, as specified in attr.type, then this is
- * the target for the symlink. If the file is not a symlink, this should
- * be ignored.
- *
- * This filename is in "CPNameLite" format. See CPNameLite.c for details.
- */
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 symlinkTarget;
-}
-#include "vmware_pack_end.h"
-HgfsReplyGetattrV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSetattr {
- HgfsRequest header;
- HgfsAttrChanges update; /* Which fields need to be updated */
- HgfsAttr attr;
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestSetattr;
-
-
-/* Version 2 of HgfsRequestSetattr */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSetattrV2 {
- HgfsRequest header;
- HgfsAttrHint hints;
- HgfsAttrV2 attr;
- HgfsHandle file; /* Opaque file ID used by the server. */
- HgfsFileName fileName; /* Filename used when file handle invalid. */
-}
-#include "vmware_pack_end.h"
-HgfsRequestSetattrV2;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSetattrV3 {
- HgfsAttrHint hints;
- HgfsAttrV2 attr;
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 fileName; /* Filename used when file handle invalid. */
-}
-#include "vmware_pack_end.h"
-HgfsRequestSetattrV3;
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySetattr {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplySetattr;
-
-
-/* Version 2 of HgfsReplySetattr */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySetattrV2 {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplySetattrV2;
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySetattrV3 {
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplySetattrV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestCreateDir {
- HgfsRequest header;
- HgfsPermissions permissions;
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestCreateDir;
-
-
-/* Version 2 of HgfsRequestCreateDir */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestCreateDirV2 {
- HgfsRequest header;
- HgfsCreateDirValid mask;
- HgfsPermissions specialPerms;
- HgfsPermissions ownerPerms;
- HgfsPermissions groupPerms;
- HgfsPermissions otherPerms;
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestCreateDirV2;
-
-
-/* Version 3 of HgfsRequestCreateDir */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestCreateDirV3 {
- HgfsCreateDirValid mask;
- HgfsPermissions specialPerms;
- HgfsPermissions ownerPerms;
- HgfsPermissions groupPerms;
- HgfsPermissions otherPerms;
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestCreateDirV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyCreateDir {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplyCreateDir;
-
-
-/* Version 2 of HgfsReplyCreateDir */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyCreateDirV2 {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplyCreateDirV2;
-
-
-/* Version 3 of HgfsReplyCreateDir */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyCreateDirV3 {
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplyCreateDirV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestDelete {
- HgfsRequest header;
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestDelete;
-
-
-/* Version 2 of HgfsRequestDelete */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestDeleteV2 {
- HgfsRequest header;
- HgfsDeleteHint hints;
- HgfsHandle file; /* Opaque file ID used by the server. */
- HgfsFileName fileName; /* Name used if the file is HGFS_HANDLE_INVALID */
-}
-#include "vmware_pack_end.h"
-HgfsRequestDeleteV2;
-
-
-/* Version 3 of HgfsRequestDelete */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestDeleteV3 {
- HgfsDeleteHint hints;
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 fileName; /* Name used if the file is HGFS_HANDLE_INVALID */
-}
-#include "vmware_pack_end.h"
-HgfsRequestDeleteV3;
-
-
-/* Deprecated */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyDelete {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplyDelete;
-
-/* Version 2 of HgfsReplyDelete */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyDeleteV2 {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplyDeleteV2;
-
-
-/* Version 2 of HgfsReplyDelete */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyDeleteV3 {
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplyDeleteV3;
-
-
-/*
- * The size of the HgfsFileName struct is variable depending on the
- * length of the name, so you can't use request->newName to get the
- * actual address of the new name, because where it starts is
- * dependant on how long the oldName is. To get the address of
- * newName, use this:
- *
- * &oldName + sizeof(HgfsFileName) + oldName.length
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestRename {
- HgfsRequest header;
- HgfsFileName oldName;
- HgfsFileName newName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestRename;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyRename {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplyRename;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestRenameV2 {
- HgfsRequest header;
- HgfsRenameHint hints;
- HgfsHandle srcFile; /* Opaque file ID to "old name" used by the server. */
- HgfsHandle targetFile; /* Opaque file ID to "old name" used by the server. */
- HgfsFileName oldName;
- HgfsFileName newName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestRenameV2;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyRenameV2 {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplyRenameV2;
-
-
-/* HgfsRequestRename and HgfsReplyRename for v3. */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestRenameV3 {
- HgfsRenameHint hints;
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 oldName;
- HgfsFileNameV3 newName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestRenameV3;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyRenameV3 {
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplyRenameV3;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestQueryVolume {
- HgfsRequest header;
- HgfsFileName fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestQueryVolume;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyQueryVolume {
- HgfsReply header;
- uint64 freeBytes;
- uint64 totalBytes;
-}
-#include "vmware_pack_end.h"
-HgfsReplyQueryVolume;
-
-
-/* HgfsRequestQueryVolume and HgfsReplyQueryVolume for v3. */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestQueryVolumeV3 {
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 fileName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestQueryVolumeV3;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyQueryVolumeV3 {
- uint64 freeBytes;
- uint64 totalBytes;
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplyQueryVolumeV3;
-
-
-
-/* New operations for Version 2 */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestServerLockChange {
- HgfsRequest header;
- HgfsHandle file;
- HgfsServerLock newServerLock;
-}
-#include "vmware_pack_end.h"
-HgfsRequestServerLockChange;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplyServerLockChange {
- HgfsReply header;
- HgfsServerLock serverLock;
-}
-#include "vmware_pack_end.h"
-HgfsReplyServerLockChange;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSymlinkCreate {
- HgfsRequest header;
- HgfsFileName symlinkName;
-
- /* This filename is in "CPNameLite" format. See CPNameLite.c for details. */
- HgfsFileName targetName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestSymlinkCreate;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySymlinkCreate {
- HgfsReply header;
-}
-#include "vmware_pack_end.h"
-HgfsReplySymlinkCreate;
-
-
-/* HgfsRequestSymlinkCreate and HgfsReplySymlinkCreate for v3. */
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsRequestSymlinkCreateV3 {
- uint64 reserved; /* Reserved for future use */
- HgfsFileNameV3 symlinkName;
-
- /* This filename is in "CPNameLite" format. See CPNameLite.c for details. */
- HgfsFileNameV3 targetName;
-}
-#include "vmware_pack_end.h"
-HgfsRequestSymlinkCreateV3;
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct HgfsReplySymlinkCreateV3 {
- uint64 reserved; /* Reserved for future use */
-}
-#include "vmware_pack_end.h"
-HgfsReplySymlinkCreateV3;
-
-
-#endif /* _HGFS_PROTO_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-
-/*
- * hgfsUtil.h --
- *
- * Utility functions and macros used by hgfs.
- */
-
-
-#ifndef _HGFSUTIL_H_
-# define _HGFSUTIL_H_
-
-# if defined(__linux__) && defined(__KERNEL__)
-# include "driver-config.h"
-# include <linux/time.h> // for time_t and timespec
- /* Include time.h in userspace code, but not in Solaris kernel code. */
-# elif defined(__FreeBSD__) && defined(_KERNEL)
- /* Do nothing. */
-# elif defined(__APPLE__) && defined(KERNEL)
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-# include "vm_basic_types.h"
-# if !defined(_STRUCT_TIMESPEC) && \
- !defined(_TIMESPEC_DECLARED) && \
- !defined(__timespec_defined) && \
- !defined(sun) && \
- !defined(__FreeBSD__) && \
- !__APPLE__ && \
- !defined(_WIN32)
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-# endif
-
-# include "hgfs.h"
-
-/* Cross-platform representation of a platform-specific error code. */
-#ifndef _WIN32
-# if defined(__KERNEL__) || defined(_KERNEL) || defined(KERNEL)
-# if defined(__linux__)
-# include <linux/errno.h>
-# elif defined(sun) || defined(__FreeBSD__) || defined(__APPLE__)
-# include <sys/errno.h>
-# endif
-# else
-# include <errno.h>
-# endif
- typedef int HgfsInternalStatus;
-#else
-# include <windows.h>
- typedef DWORD HgfsInternalStatus;
-#endif
-
-/*
- * Unfortunately, we need a catch-all "generic error" to use with
- * HgfsInternalStatus, because there are times when cross-platform code needs
- * to return its own errors along with errors from platform specific code.
- *
- * Using -1 should be safe because we expect our platforms to use zero as
- * success and a positive range of numbers as error values.
- */
-#define HGFS_INTERNAL_STATUS_ERROR (-1)
-
-#ifndef _WIN32
-/*
- * This error code is used to notify the client that some of the parameters passed
- * (e.g. file handles) are not supported. Clients are expected to correct
- * the parameter (e.g. pass file name instead) and retry.
- *
- * Note that this error code is artificially made up and in future may conflict
- * with an "official" error code when added.
- */
-#define EPARAMETERNOTSUPPORTED (MAX_INT32 - 1)
-#endif
-
-/*
- * FreeBSD (pre-6.0) does not define EPROTO, so we'll define our own error code.
- */
-#if defined(__FreeBSD__) && !defined(EPROTO)
-#define EPROTO (ELAST + 1)
-#endif
-
-#define HGFS_NAME_BUFFER_SIZE(request) (HGFS_PACKET_MAX - (sizeof *request - 1))
-#define HGFS_NAME_BUFFER_SIZET(sizet) (HGFS_PACKET_MAX - ((sizet) - 1))
-
-#ifndef _WIN32
-/*
- * Routines for converting between Win NT and unix time formats. The
- * hgfs attributes use the NT time formats, so the linux driver and
- * server have to convert back and forth. [bac]
- */
-
-uint64 HgfsConvertToNtTime(time_t unixTime, // IN
- long nsec); // IN
-static INLINE uint64
-HgfsConvertTimeSpecToNtTime(const struct timespec *unixTime) // IN
-{
- return HgfsConvertToNtTime(unixTime->tv_sec, unixTime->tv_nsec);
-}
-
-int HgfsConvertFromNtTime(time_t * unixTime, // OUT
- uint64 ntTime); // IN
-int HgfsConvertFromNtTimeNsec(struct timespec *unixTime, // OUT
- uint64 ntTime); // IN
-#endif /* !def(_WIN32) */
-
-HgfsStatus HgfsConvertFromInternalStatus(HgfsInternalStatus status); // IN
-
-#endif /* _HGFSUTIL_H_ */
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * includeCheck.h --
- *
- * Restrict include file use.
- *
- * In every .h file, define one or more of these
- *
- * INCLUDE_ALLOW_VMX
- * INCLUDE_ALLOW_USERLEVEL
- * INCLUDE_ALLOW_VMMEXT
- * INCLUDE_ALLOW_VMCORE
- * INCLUDE_ALLOW_MODULE
- * INCLUDE_ALLOW_VMNIXMOD
- * INCLUDE_ALLOW_VMKERNEL
- * INCLUDE_ALLOW_DISTRIBUTE
- * INCLUDE_ALLOW_VMK_MODULE
- * INCLUDE_ALLOW_VMKDRIVERS
- * INCLUDE_ALLOW_VMIROM
- *
- * Then include this file.
- *
- * Any file that has INCLUDE_ALLOW_DISTRIBUTE defined will potentially
- * be distributed in source form along with GPLed code. Ensure
- * that this is acceptable.
- */
-
-
-/*
- * Declare a VMCORE-only variable to help classify object
- * files. The variable goes in the common block and does
- * not create multiple definition link-time conflicts.
- */
-
-#if defined VMCORE && defined VMX86_DEVEL && defined VMX86_DEBUG && \
- defined linux && !defined MODULE && \
- !defined COMPILED_WITH_VMCORE
-#define COMPILED_WITH_VMCORE compiled_with_vmcore
-#ifdef ASM
- .comm compiled_with_vmcore, 0
-#else
- asm(".comm compiled_with_vmcore, 0");
-#endif /* ASM */
-#endif
-
-
-#if defined VMCORE && \
- !(defined VMX86_VMX || defined VMM || \
- defined MONITOR_APP || defined VMMON)
-#error "Makefile problem: VMCORE without VMX86_VMX or \
- VMM or MONITOR_APP or MODULE."
-#endif
-
-#if defined VMCORE && !defined INCLUDE_ALLOW_VMCORE
-#error "The surrounding include file is not allowed in vmcore."
-#endif
-#undef INCLUDE_ALLOW_VMCORE
-
-#if defined VMX86_VMX && !defined VMCORE && \
- !(defined INCLUDE_ALLOW_VMX || defined INCLUDE_ALLOW_USERLEVEL)
-#error "The surrounding include file is not allowed in the VMX."
-#endif
-#undef INCLUDE_ALLOW_VMX
-
-#if defined USERLEVEL && !defined VMX86_VMX && !defined VMCORE && \
- !defined INCLUDE_ALLOW_USERLEVEL
-#error "The surrounding include file is not allowed at userlevel."
-#endif
-#undef INCLUDE_ALLOW_USERLEVEL
-
-#if defined VMM && !defined VMCORE && \
- !defined INCLUDE_ALLOW_VMMEXT
-#error "The surrounding include file is not allowed in the monitor."
-#endif
-#undef INCLUDE_ALLOW_VMMEXT
-
-#if defined MODULE && !defined VMKERNEL_MODULE && !defined VMNIXMOD && \
- !defined VMMON && !defined INCLUDE_ALLOW_MODULE
-#error "The surrounding include file is not allowed in driver modules."
-#endif
-#undef INCLUDE_ALLOW_MODULE
-
-#if defined VMMON && !defined INCLUDE_ALLOW_VMMON
-#error "The surrounding include file is not allowed in vmmon."
-#endif
-#undef INCLUDE_ALLOW_VMMON
-
-#if defined VMKERNEL && !defined INCLUDE_ALLOW_VMKERNEL
-#error "The surrounding include file is not allowed in the vmkernel."
-#endif
-#undef INCLUDE_ALLOW_VMKERNEL
-
-#if defined GPLED_CODE && !defined INCLUDE_ALLOW_DISTRIBUTE
-#error "The surrounding include file is not allowed in GPL code."
-#endif
-#undef INCLUDE_ALLOW_DISTRIBUTE
-
-#if defined VMKERNEL_MODULE && !defined VMKERNEL && \
- !defined INCLUDE_ALLOW_VMK_MODULE && !defined INCLUDE_ALLOW_VMKDRIVERS
-#error "The surrounding include file is not allowed in vmkernel modules."
-#endif
-#undef INCLUDE_ALLOW_VMK_MODULE
-#undef INCLUDE_ALLOW_VMKDRIVERS
-
-#if defined VMNIXMOD && !defined INCLUDE_ALLOW_VMNIXMOD
-#ifndef VMNIXMOD_VM
-#error "The surrounding include file is not allowed in vmnixmod."
-#endif
-#endif
-#undef INCLUDE_ALLOW_VMNIXMOD
-
-#if defined VMIROM && ! defined INCLUDE_ALLOW_VMIROM
-#error "The surrounding include file is not allowed in vmirom."
-#endif
-#undef INCLUDE_ALLOW_VMIROM
retry:
if (op == HGFS_OP_DELETE_FILE) {
- opUsed = atomic_read(&hgfsVersionDeleteFile);
+ opUsed = hgfsVersionDeleteFile;
} else {
- opUsed = atomic_read(&hgfsVersionDeleteDir);
+ opUsed = hgfsVersionDeleteDir;
}
if (opUsed == HGFS_OP_DELETE_FILE_V3 ||
if (opUsed == HGFS_OP_DELETE_DIR_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionDeleteDir, HGFS_OP_DELETE_DIR);
+ hgfsVersionDeleteDir = HGFS_OP_DELETE_DIR;
goto retry;
} else if (opUsed == HGFS_OP_DELETE_FILE_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDelete: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionDeleteFile, HGFS_OP_DELETE_FILE);
+ hgfsVersionDeleteFile = HGFS_OP_DELETE_FILE;
goto retry;
}
}
retry:
- opUsed = atomic_read(&hgfsVersionCreateDir);
+ opUsed = hgfsVersionCreateDir;
result = HgfsPackCreateDirRequest(dentry, mode, opUsed, req);
if (result != 0) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: error packing request\n"));
if (opUsed == HGFS_OP_CREATE_DIR_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: Version 3 not "
"supported. Falling back to version 2.\n"));
- atomic_set(&hgfsVersionCreateDir, HGFS_OP_CREATE_DIR_V2);
+ hgfsVersionCreateDir = HGFS_OP_CREATE_DIR_V2;
goto retry;
} else if (opUsed == HGFS_OP_CREATE_DIR_V2) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsMkdir: Version 2 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionCreateDir, HGFS_OP_CREATE_DIR);
+ hgfsVersionCreateDir = HGFS_OP_CREATE_DIR;
goto retry;
}
}
retry:
- opUsed = atomic_read(&hgfsVersionRename);
+ opUsed = hgfsVersionRename;
if (opUsed == HGFS_OP_RENAME_V3) {
HgfsRequestRenameV3 *request = (HgfsRequestRenameV3 *)HGFS_REQ_PAYLOAD_V3(req);
HgfsRequest *header = (HgfsRequest *)HGFS_REQ_PAYLOAD(req);
if (result == -EPROTO) {
/* Retry with older version(s). Set globally. */
if (opUsed == HGFS_OP_RENAME_V3) {
- atomic_set(&hgfsVersionRename, HGFS_OP_RENAME);
+ hgfsVersionRename = HGFS_OP_RENAME;
goto retry;
} else {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsRename: server "
}
retry:
- opUsed = atomic_read(&hgfsVersionCreateSymlink);
+ opUsed = hgfsVersionCreateSymlink;
result = HgfsPackSymlinkCreateRequest(dentry, symname, opUsed, req);
if (result != 0) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: error packing request\n"));
if (opUsed == HGFS_OP_CREATE_SYMLINK_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSymlink: Version 3 "
"not supported. Falling back to version 2.\n"));
- atomic_set(&hgfsVersionCreateSymlink, HGFS_OP_CREATE_SYMLINK);
+ hgfsVersionCreateSymlink = HGFS_OP_CREATE_SYMLINK;
goto retry;
} else {
LOG(6, (KERN_DEBUG "VMware hgfs: HgfsSymlink: symlink was not "
retry:
/* Fill out the request packet. */
- opUsed = atomic_read(&hgfsVersionSetattr);
+ opUsed = hgfsVersionSetattr;
result = HgfsPackSetattrRequest(iattr, dentry, allowHandleReuse,
opUsed, req, &changed);
if (result != 0 || !changed) {
if (opUsed == HGFS_OP_SETATTR_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: Version 3 "
"not supported. Falling back to version 2.\n"));
- atomic_set(&hgfsVersionSetattr, HGFS_OP_SETATTR_V2);
+ hgfsVersionSetattr = HGFS_OP_SETATTR_V2;
goto retry;
} else if (opUsed == HGFS_OP_SETATTR_V2) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsSetattr: Version 2 "
"not supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionSetattr, HGFS_OP_SETATTR);
+ hgfsVersionSetattr = HGFS_OP_SETATTR;
goto retry;
}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * kernelStubs.h
- *
- * KernelStubs implements some userspace library functions in terms
- * of kernel functions to allow library userspace code to be used in a
- * kernel.
- */
-
-#ifndef __KERNELSTUBS_H__
-#define __KERNELSTUBS_H__
-
-#ifdef linux
-# ifndef __KERNEL__
-# error "__KERNEL__ is not defined"
-# endif
-# include "driver-config.h" // Must be included before any other header files
-# include "vm_basic_types.h"
-# include <linux/kernel.h>
-# include <linux/string.h>
-#elif defined(_WIN32)
-# include "vm_basic_types.h"
-# include <ntddk.h> /* kernel memory APIs */
-# include <stdio.h> /* for _vsnprintf, vsprintf */
-# include <stdarg.h> /* for va_start stuff */
-# include <stdlib.h> /* for min macro. */
-# include "vm_assert.h" /* Our assert macros */
-#elif defined(__FreeBSD__)
-# include "vm_basic_types.h"
-# ifndef _KERNEL
-# error "_KERNEL is not defined"
-# endif
-# include <sys/types.h>
-# include <sys/malloc.h>
-# include <sys/param.h>
-# include <sys/kernel.h>
-# include <machine/stdarg.h>
-# include <sys/libkern.h>
-# include "vm_assert.h"
-#elif defined(__APPLE__)
-# include "vm_basic_types.h"
-# ifndef KERNEL
-# error "KERNEL is not defined"
-# endif
-# include <stdarg.h>
-# include <string.h>
-# elif defined(sun)
-# include "vm_basic_types.h"
-# include <sys/types.h>
-# include <sys/varargs.h>
-#endif
-
-/*
- * Function Prototypes
- */
-
-#if defined(linux) || defined(__APPLE__) || defined (sun)
-
-# ifdef linux /* if (linux) { */
-char *strdup(const char *source);
-# endif
-
-/* Shared between Linux and Apple kernel stubs. */
-void *malloc(size_t size);
-void free(void *mem);
-void *calloc(size_t num, size_t len);
-void *realloc(void *ptr, size_t newSize);
-
-#elif defined(_WIN32) /* } else if (_WIN32) { */
-
-#if (_WIN32_WINNT == 0x0400)
-/* The following declarations are missing on NT4. */
-typedef unsigned int UINT_PTR;
-typedef unsigned int SIZE_T;
-
-/* No free with tag availaible on NT4 kernel! */
-#define KRNL_STUBS_FREE(P,T) ExFreePool((P))
-
-#else /* _WIN32_WINNT */
-#define KRNL_STUBS_FREE(P,T) ExFreePoolWithTag((P),(T))
-/* Win 2K and later useful kernel function, documented but not declared! */
-NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, IN ULONG Tag);
-#endif /* _WIN32_WINNT */
-
-#elif defined(__FreeBSD__) /* } else if (FreeBSD) { */
-
-/* Kernel memory on FreeBSD is tagged for statistics and sanity checking. */
-MALLOC_DECLARE(M_VMWARE_TEMP);
-
-/*
- * On FreeBSD, the general memory allocator for both userland and the kernel is named
- * malloc, but the kernel malloc() takes more arguments. The following alias & macros
- * work around this, to provide the standard malloc() API for userspace code that is
- * being used in the kernel.
- */
-
-# undef malloc
-
-static INLINE void *
-__compat_malloc(unsigned long size, struct malloc_type *type, int flags) {
- return malloc(size, type, flags);
-}
-
-# define malloc(size) __compat_malloc(size, M_VMWARE_TEMP, M_NOWAIT)
-# define calloc(count, size) __compat_malloc((count) * (size), \
- M_VMWARE_TEMP, M_NOWAIT|M_ZERO)
-# define realloc(buf, size) realloc(buf, size, M_VMWARE_TEMP, M_NOWAIT)
-# define free(buf) free(buf, M_VMWARE_TEMP)
-# define strchr(s,c) index(s,c)
-# define strrchr(s,c) rindex(s,c)
-
-#endif /* } */
-
-/*
- * Stub functions we provide.
- */
-
-void Panic(const char *fmt, ...);
-
-char *Str_Strcpy(char *buf, const char *src, size_t maxSize);
-int Str_Vsnprintf(char *str, size_t size, const char *format,
- va_list arguments);
-char *Str_Vasprintf(size_t *length, const char *format,
- va_list arguments);
-char *Str_Asprintf(size_t *length, const char *Format, ...);
-
-/*
- * Functions the driver must implement for the stubs.
- */
-EXTERN void Debug(const char *fmt, ...);
-
-
-#endif /* __KERNELSTUBS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * message.h --
- *
- * Second layer of the internal communication channel between guest
- * applications and vmware
- */
-
-#ifndef __MESSAGE_H__
-# define __MESSAGE_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vm_basic_types.h"
-
-
-typedef struct Message_Channel Message_Channel;
-
-
-/*
- * These functions must be implemented by any external Message
- * transport implementation. Some examples include crossTalk,
- * a network socket, or a Microsoft Hypervisor backdoor.
- *
- * These external functions mirror the same corresponding Message_*
- * functions below.
- */
-typedef Message_Channel *(*MessageOpenProcType)(uint32 proto);
-
-typedef Bool (*MessageGetReadEventProcType)(Message_Channel *chan,
- int64 *readEvent);
-
-typedef Bool (*MessageSendProcType)(Message_Channel *chan,
- const unsigned char *buf,
- size_t bufSize);
-typedef Bool (*MessageReceiveProcType)(Message_Channel *chan,
- unsigned char **buf,
- size_t *bufSize);
-typedef Bool (*MessageCloseProcType)(Message_Channel *chan);
-
-
-/*
- * This tells the message layer to use an alternate transport
- * for messages. By default, we use the backdoor, so this function
- * overrides that default at runtime and switches everything over to
- * an alternate transport.
- */
-void Message_SetTransport(MessageOpenProcType openProc,
- MessageGetReadEventProcType getReadEeventProc,
- MessageSendProcType sendProc,
- MessageReceiveProcType receiveProc,
- MessageCloseProcType closeProc);
-
-void MessageStub_RegisterTransport(void);
-
-Message_Channel *
-Message_Open(uint32 proto); // IN
-
-/*
- * This allows higher levels of the IPC stack to use an event to detect
- * when a message has arrived. This allows an interrupt-model rather than
- * continually calling Message_Receive in a busy loop. This may only be supported
- * by some transports. The backdoor does not, so the IPC code will still
- * have to poll in those cases.
- */
-Bool
-Message_GetReadEvent(Message_Channel *chan, // IN
- int64 *event); // OUT
-
-Bool
-Message_Send(Message_Channel *chan, // IN/OUT
- const unsigned char *buf, // IN
- size_t bufSize); // IN
-
-Bool
-Message_Receive(Message_Channel *chan, // IN/OUT
- unsigned char **buf, // OUT
- size_t *bufSize); // OUT
-
-Bool
-Message_Close(Message_Channel *chan); // IN/OUT
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MESSAGE_H__ */
MODULE_PARM_DESC(LOGLEVEL_THRESHOLD, "Set verbosity (0 means no log, 10 means very verbose, 4 is default)");
#endif
+char *HOST_IP = NULL;
+int HOST_PORT = 2000; /* Defaulted to 2000. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
+module_param(HOST_IP, charp, 0444);
+module_param(HOST_PORT, int, 0444);
+#else
+MODULE_PARM(HOST_IP, "s");
+MODULE_PARM(HOST_PORT, "i");
+#endif
+
/* Module information. */
MODULE_AUTHOR("VMware, Inc.");
MODULE_DESCRIPTION("VMware Host/Guest File System");
#define LOG(level, args)
#endif
+extern char *HOST_IP;
+extern int HOST_PORT;
+
/* Blocksize to be set in superblock. (XXX how is this used?) */
#define HGFS_BLOCKSIZE 1024
#define FILE_SET_FI_P(file, info) do { (file)->private_data = info; } while (0)
#define FILE_GET_FI_P(file) ((HgfsFileInfo *)(file)->private_data)
-/*
- * When waking up the request handler thread, these are the possible operations
- * one can ask it to perform.
- */
-#define HGFS_REQ_THREAD_SEND (1 << 0)
-#define HGFS_REQ_THREAD_EXIT (1 << 1)
-
/* Data kept in each superblock in sb->u. */
typedef struct HgfsSuperInfo {
uid_t uid; /* UID of user who mounted this fs. */
*/
extern spinlock_t hgfsBigLock;
-/*
- * The request handler thread uses hgfsReqThreadWait to wake up and handle
- * IO. Possible operations include:
- * -Sending outgoing HGFS requests.
- * -Shutting down the request handler thread.
- *
- * Finally, we use hgfsReqThread to synchronize the stopping of the
- * backdoor handler thread.
- */
-extern long hgfsReqThreadFlags;
-extern wait_queue_head_t hgfsReqThreadWait;
-extern struct task_struct *hgfsReqThread;
-
/* Hgfs filesystem structs. */
extern struct super_operations HgfsSuperOperations;
extern struct dentry_operations HgfsDentryOperations;
/* Other global state. */
extern compat_kmem_cache *hgfsReqCache;
extern compat_kmem_cache *hgfsInodeCache;
-extern RpcOut *hgfsRpcOut;
-extern unsigned int hgfsIdCounter;
-extern struct list_head hgfsReqsUnsent;
-
-extern atomic_t hgfsVersionOpen;
-extern atomic_t hgfsVersionRead;
-extern atomic_t hgfsVersionWrite;
-extern atomic_t hgfsVersionClose;
-extern atomic_t hgfsVersionSearchOpen;
-extern atomic_t hgfsVersionSearchRead;
-extern atomic_t hgfsVersionSearchClose;
-extern atomic_t hgfsVersionGetattr;
-extern atomic_t hgfsVersionSetattr;
-extern atomic_t hgfsVersionCreateDir;
-extern atomic_t hgfsVersionDeleteFile;
-extern atomic_t hgfsVersionDeleteDir;
-extern atomic_t hgfsVersionRename;
-extern atomic_t hgfsVersionQueryVolumeInfo;
-extern atomic_t hgfsVersionCreateSymlink;
+
+extern HgfsOp hgfsVersionOpen;
+extern HgfsOp hgfsVersionRead;
+extern HgfsOp hgfsVersionWrite;
+extern HgfsOp hgfsVersionClose;
+extern HgfsOp hgfsVersionSearchOpen;
+extern HgfsOp hgfsVersionSearchRead;
+extern HgfsOp hgfsVersionSearchClose;
+extern HgfsOp hgfsVersionGetattr;
+extern HgfsOp hgfsVersionSetattr;
+extern HgfsOp hgfsVersionCreateDir;
+extern HgfsOp hgfsVersionDeleteFile;
+extern HgfsOp hgfsVersionDeleteDir;
+extern HgfsOp hgfsVersionRename;
+extern HgfsOp hgfsVersionQueryVolumeInfo;
+extern HgfsOp hgfsVersionCreateSymlink;
#endif // _HGFS_DRIVER_MODULE_H_
}
retry:
- opUsed = atomic_read(&hgfsVersionRead);
+ opUsed = hgfsVersionRead;
if (opUsed == HGFS_OP_READ_V3) {
HgfsRequest *header;
HgfsRequestReadV3 *request;
if (opUsed == HGFS_OP_READ_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDoRead: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionRead, HGFS_OP_READ);
+ hgfsVersionRead = HGFS_OP_READ;
goto retry;
}
break;
}
retry:
- opUsed = atomic_read(&hgfsVersionWrite);
+ opUsed = hgfsVersionWrite;
if (opUsed == HGFS_OP_WRITE_V3) {
HgfsRequest *header;
HgfsRequestWriteV3 *request;
if (opUsed == HGFS_OP_WRITE_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsDoWrite: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionWrite, HGFS_OP_WRITE);
+ hgfsVersionWrite = HGFS_OP_WRITE;
goto retry;
}
break;
#include "module.h"
#include "request.h"
+#include "transport.h"
#include "fsutil.h"
#include "vm_assert.h"
-static int HgfsWaitRequestReply(HgfsReq *req);
-
-/*
- * Private function implementations.
- */
+static uint64 hgfsIdCounter = 0;
+static spinlock_t hgfsIdLock = SPIN_LOCK_UNLOCKED;
-/*
- *----------------------------------------------------------------------
- *
- * HgfsWaitRequestReply --
- *
- * Wait for the reply to a request that we sent.
- *
- * Results:
- * Returns zero when the answer has been received, -ERESTARTSYS if
- * interrupted, or -EPROTO if there was a backdoor error. It is important
- * that -ERESTARTSYS be returned in the event of a signal getting caught,
- * because calling functions test the return value to determine
- * whether or not to free the request object.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static int
-HgfsWaitRequestReply(HgfsReq *req) // IN/OUT: Request object
-{
- int err = 0;
- long timeleft;
-
- ASSERT(req);
-
- if (!req) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsWaitRequestReply: null req\n"));
- return -EINVAL;
- }
-
- timeleft = wait_event_timeout(req->queue,
- (req->state == HGFS_REQ_STATE_COMPLETED ||
- req->state == HGFS_REQ_STATE_ERROR),
- HGFS_REQUEST_TIMEOUT);
- /*
- * Did we time out? If so, abandon the request. We have to be careful,
- * because a timeout means that the request is still on a list somewhere.
- */
- if (timeleft == 0) {
- spin_lock(&hgfsBigLock);
- if (!list_empty(&req->list)) {
- list_del_init(&req->list);
- }
- spin_unlock(&hgfsBigLock);
-
- /*
- * Notice that we're completely ignoring any pending signals. That's
- * because the request timed out; it was not interrupted. There's no
- * point in having the client retry the syscall (through -ERESTARTSYS) if
- * it wasn't actually interrupted.
- */
- err = -EIO;
- } else if (req->state == HGFS_REQ_STATE_ERROR) {
- /*
- * If the backdoor exploded, let's modify the return value so the client
- * knows about it. We only care about this if we didn't timeout.
- */
- err = -EPROTO;
- }
-
- LOG(8, (KERN_DEBUG "VMware hgfs: HgfsWaitRequestReply: request finished, "
- "code %d\n", err));
- return err;
-}
-
-
-/*
- * Public function implementations.
- */
-
/*
*----------------------------------------------------------------------
*
init_waitqueue_head(&req->queue);
req->payloadSize = 0;
req->state = HGFS_REQ_STATE_ALLOCATED;
-
/* Setup the packet prefix. */
memcpy(req->packet, HGFS_SYNC_REQREP_CLIENT_CMD,
HGFS_SYNC_REQREP_CLIENT_CMD_LEN);
-
- /* Atomically increment counter and set ID. */
- spin_lock(&hgfsBigLock);
- req->id = hgfsIdCounter++;
- spin_unlock(&hgfsBigLock);
-
+ spin_lock(&hgfsIdLock);
+ req->id = hgfsIdCounter;
+ hgfsIdCounter++;
+ spin_unlock(&hgfsIdLock);
return req;
}
*
* HgfsSendRequest --
*
- * Add an HGFS request to the request queue, wake up the backdoor
- * handler, and wait for the reply.
+ * Send out an HGFS request via transport layer, and wait for the reply.
*
* Results:
- * Returns zero on success, -ERESTARTSYS if interrupted (this value will
- * be returned by HgfsWaitRequestReply), negative error
- * otherwise. Callers use the -ERESTARTSYS return value to determine
- * whether they should free the request object before exiting.
+ * Returns zero on success, negative number on error.
*
* Side effects:
* None
int
HgfsSendRequest(HgfsReq *req) // IN/OUT: Outgoing request
{
- int error;
+ int ret;
ASSERT(req);
ASSERT(req->payloadSize <= HGFS_PACKET_MAX);
LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendRequest: Sending request id %d\n",
req->id));
- /*
- * Add the request to the queue, wake up the backdoor handler thread, and
- * wait for a reply.
- */
- spin_lock(&hgfsBigLock);
- list_add_tail(&req->list, &hgfsReqsUnsent);
- spin_unlock(&hgfsBigLock);
-
- set_bit(HGFS_REQ_THREAD_SEND, &hgfsReqThreadFlags);
- wake_up_interruptible(&hgfsReqThreadWait);
- error = HgfsWaitRequestReply(req);
+ ret = HgfsTransportSendRequest(req);
+ if (ret == 0) { /* Send succeeded. */
+ wait_event(req->queue, req->state == HGFS_REQ_STATE_COMPLETED);
+ } /* else send failed. */
- return error;
+ LOG(8, (KERN_DEBUG "VMware hgfs: HgfsSendRequest: request finished, "
+ "return %d\n", ret));
+ return ret;
}
{
ASSERT(hgfsReqCache);
- /* Atomically decrement counter. */
- spin_lock(&hgfsBigLock);
- hgfsIdCounter--;
- spin_unlock(&hgfsBigLock);
-
if (req != NULL) {
kmem_cache_free(hgfsReqCache, req);
}
return rep->status;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsCompleteReq --
+ *
+ * Copies the reply packet into the request structure and wakes up
+ * the associated client.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+HgfsCompleteReq(HgfsReq *req, // IN: Request
+ char const *reply, // IN: Reply packet
+ size_t replySize) // IN: Size of reply packet
+{
+ ASSERT(req);
+ ASSERT(reply);
+ ASSERT(replySize <= HGFS_PACKET_MAX);
+
+ memcpy(HGFS_REQ_PAYLOAD(req), reply, replySize);
+ req->payloadSize = replySize;
+ req->state = HGFS_REQ_STATE_COMPLETED;
+ ASSERT(!list_empty(&req->list));
+ list_del_init(&req->list);
+ /* Wake up the client process waiting for the reply to this request. */
+ wake_up(&req->queue);
+}
* HGFS_REQ_STATE_UNSENT:
* The filesystem half of the driver has filled in the request fields
* and placed the request in the global unsent list. It is now the
- * backdoor handler's responsibility to submit this request to
- * the backdoor. Requests in this state are on the global unsent list.
+ * request handler's responsibility to submit this request to
+ * the channel. Requests in this state are on the global unsent list.
*
- * HGFS_REQ_STATE_SENT:
- * The backdoor handler has sent the packet, but the reply will arrive
- * asynchronously. The request is now on the sent list, and whenever
- * the reply arrives, the backdoor handler will remove the request from
- * the sent list and stuff the reply into the request's packet buffer.
+ * HGFS_REQ_STATE_SUBMITTED:
+ * The packet has been sent, but the reply will arrive asynchronously.
+ * The request will be on the hgfsRepPending list, and whenever
+ * the reply arrives, the reply handler will remove the request from
+ * the hgfsRepPending list and stuff the reply into the request's
+ * packet buffer.
*
- * HGFS_REQ_STATE_ERROR:
- * The backdoor handler encountered an error while sending the request
- * or getting the reply. The filesystem half of the driver should
- * free the request. Requests in this state are not on any list.
+ * This is only for asynchronous channel communication.
*
* HGFS_REQ_STATE_COMPLETED:
- * The backdoor handler sent the request and received a reply. The reply
+ * The request handler sent the request and received a reply. The reply
* is stuffed in the request's packet buffer. Requests in this state
* are not on any list.
*/
typedef enum {
HGFS_REQ_STATE_ALLOCATED,
HGFS_REQ_STATE_UNSENT,
- HGFS_REQ_STATE_SENT,
- HGFS_REQ_STATE_ERROR,
+ HGFS_REQ_STATE_SUBMITTED,
HGFS_REQ_STATE_COMPLETED,
} HgfsState;
HgfsReq *HgfsGetNewRequest(void);
int HgfsSendRequest(HgfsReq *req);
void HgfsFreeRequest(HgfsReq *req);
-HgfsStatus HgfsReplyStatus(HgfsReq *req); // IN
+HgfsStatus HgfsReplyStatus(HgfsReq *req);
+void HgfsCompleteReq(HgfsReq *req,
+ char const *reply,
+ size_t replySize);
#endif // _HGFS_DRIVER_REQUEST_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * rpcout.h --
- *
- * Remote Procedure Call between VMware and guest applications
- * C declarations
- */
-
-
-#ifndef __RPCOUT_H__
-# define __RPCOUT_H__
-
-#include "vm_basic_types.h"
-
-#define RPCI_PROTOCOL_NUM 0x49435052 /* 'RPCI' ;-) */
-
-typedef struct RpcOut RpcOut;
-
-RpcOut *RpcOut_Construct(void);
-void RpcOut_Destruct(RpcOut *out);
-Bool RpcOut_start(RpcOut *out);
-Bool RpcOut_send(RpcOut *out, char const *request, size_t reqLen,
- char const **reply, size_t *repLen);
-Bool RpcOut_stop(RpcOut *out);
-
-
-/*
- * This is the only method needed to send a message to vmware for
- * 99% of uses. I'm leaving the others defined here so people know
- * they can be exported again if the need arises. [greg]
- */
-Bool RpcOut_sendOne(char **reply, size_t *repLen, char const *reqFmt, ...);
-
-/*
- * A new version of the above function that works with UTF-8 strings
- * and other data that would be corrupted by Win32's FormatMessage
- * function (which is used by RpcOut_sendOne()).
- */
-
-Bool RpcOut_SendOneRaw(void *request, size_t reqLen, char **reply, size_t *repLen);
-
-#endif /* __RPCOUT_H__ */
}
retry:
- opUsed = atomic_read(&hgfsVersionQueryVolumeInfo);
+ opUsed = hgfsVersionQueryVolumeInfo;
result = HgfsPackQueryVolumeRequest(dentryToUse, opUsed, req);
if (result != 0) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: error packing request\n"));
if (opUsed == HGFS_OP_QUERY_VOLUME_INFO_V3) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsStatfs: Version 3 not "
"supported. Falling back to version 1.\n"));
- atomic_set(&hgfsVersionQueryVolumeInfo, HGFS_OP_QUERY_VOLUME_INFO);
+ hgfsVersionQueryVolumeInfo = HGFS_OP_QUERY_VOLUME_INFO;
goto retry;
}
break;
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * tcp.c --
+ *
+ * Provides TCP channel to the HGFS client.
+ *
+ * Compiled conditionally.
+ * Need to specify host ip at module load to enable the channel.
+ */
+
+/* Must come before any kernel header file. */
+#include "driver-config.h"
+
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/inet.h>
+#include <linux/errno.h>
+
+#include "compat_kernel.h"
+#include "compat_mutex.h"
+#include "compat_version.h"
+#include "compat_sched.h"
+#include "compat_sock.h"
+#include "vm_assert.h"
+
+#include "hgfsProto.h"
+
+#include "hgfsDevLinux.h"
+#include "module.h"
+#include "tcp.h"
+
+#ifndef HGFS_TCP_SERVER
+/* Should be removed after server-side changes are checked in. */
+typedef struct HgfsTcpHeader {
+ uint32 version; /* Packet magic. */
+ uint32 packetLen; /* The length of the packet to follow. */
+} HgfsTcpHeader;
+
+#define HGFS_TCP_VERSION1 1
+#endif
+
+/* HGFS receive buffer. */
+typedef struct HgfsTcpRecvBuffer {
+ HgfsTcpHeader header; /* Buffer for receiving header. */
+ char data[HGFS_PACKET_MAX]; /* Buffer for receiving packet. */
+ uint32 state; /* Reply receive state. */
+} HgfsTcpRecvBuffer;
+
+/* Recv states for the recvBuffer. */
+typedef enum {
+ HGFS_TCP_CONN_RECV_HEADER,
+ HGFS_TCP_CONN_RECV_DATA,
+} HgfsTcpRecvState;
+
+/* No lock to protect recvBuffer. It is accessed only by the recv thread. */
+static HgfsTcpRecvBuffer recvBuffer;
+
+HgfsTransportChannel tcpChannel;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTcpChannelOpen --
+ *
+ * Connect to HGFS TCP server in an idempotent way.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Bool
+HgfsTcpChannelOpen(void)
+{
+ int error;
+ struct socket *sock;
+ struct sockaddr_in addr;
+
+ compat_mutex_lock(&tcpChannel.connLock);
+ if (tcpChannel.status == HGFS_CHANNEL_CONNECTED) {
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return TRUE;
+ } else if (tcpChannel.status == HGFS_CHANNEL_UNINITIALIZED) {
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return FALSE;
+ }
+
+ if (tcpChannel.priv != NULL) {
+ sock_release(tcpChannel.priv);
+ }
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = in_aton(HOST_IP);
+ addr.sin_port = htons(HOST_PORT);
+
+ error = compat_sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+ if (error < 0) {
+ LOG(8, ("%s: sock_create_kern failed: %d.\n", __FUNCTION__, error));
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return FALSE;
+ }
+
+ error = sock->ops->connect(sock, (struct sockaddr *)&addr,
+ sizeof addr, 0);
+ if (error < 0) {
+ LOG(8, ("%s: connect failed: %d.\n", __FUNCTION__, error));
+ if (sock) {
+ sock_release(sock);
+ }
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return FALSE;
+ }
+
+ tcpChannel.priv = sock;
+
+ tcpChannel.status = HGFS_CHANNEL_CONNECTED;
+ LOG(8, ("%s: tcp channel conneted.\n", __FUNCTION__));
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return TRUE;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTcpChannelClose --
+ *
+ * Close the tcp channel in an idempotent way.
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HgfsTcpChannelClose(void)
+{
+ compat_mutex_lock(&tcpChannel.connLock);
+ if (tcpChannel.status != HGFS_CHANNEL_CONNECTED) {
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return;
+ }
+
+ if (tcpChannel.priv != NULL) {
+ sock_release(tcpChannel.priv);
+ tcpChannel.priv = NULL;
+ }
+ tcpChannel.status = HGFS_CHANNEL_DISCONNECTED;
+ compat_mutex_unlock(&tcpChannel.connLock);
+ LOG(8, ("%s: tcp channel closed.\n", __FUNCTION__));
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTcpRecvMsg --
+ *
+ * Receive the message on the socket.
+ *
+ * Results:
+ * On success returns number of bytes received.
+ * On failure returns the negative errno.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsTcpRecvMsg(struct socket *socket, // IN: TCP socket
+ char *buffer, // IN: Buffer to recv the message
+ size_t bufferLen) // IN: Buffer length
+{
+ struct iovec iov;
+ struct msghdr msg;
+ mm_segment_t fs;
+ int ret;
+ int flags = 0;
+
+ memset(&msg, 0, sizeof msg);
+ msg.msg_flags = flags;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ iov.iov_base = buffer;
+ iov.iov_len = bufferLen;
+
+ /* get_fs/set_fs give us more privilidges so that we are able to call
+ sock_recvmsg from kernel. */
+ fs = get_fs();
+ set_fs(get_ds());
+ ret = sock_recvmsg(socket, &msg, bufferLen, flags);
+ set_fs(fs);
+
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTcpChannelRecvAsync --
+ *
+ * Receive the packet.
+ *
+ * Results:
+ * On success returns number of bytes received.
+ * On failure returns the negative errno.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsTcpChannelRecvAsync(char **replyPacket, // IN/OUT: Reply buffer
+ size_t *packetSize) // IN/OUT: Reply packet size
+{
+ int ret = -EIO;
+
+ ASSERT(replyPacket);
+ ASSERT(packetSize);
+
+ if (tcpChannel.status != HGFS_CHANNEL_CONNECTED) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: Connection lost.\n", __FUNCTION__));
+ return -ENOTCONN;
+ }
+
+ switch(recvBuffer.state) {
+ case HGFS_TCP_CONN_RECV_HEADER:
+ ret = HgfsTcpRecvMsg(tcpChannel.priv, (char *)&recvBuffer.header,
+ sizeof(HgfsTcpHeader));
+ if (ret > 0) {
+ ASSERT(ret == sizeof(HgfsTcpHeader));
+ recvBuffer.state = HGFS_TCP_CONN_RECV_DATA;
+ ret = 0;
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s: header received. packet len: %d"
+ "\n", __FUNCTION__, recvBuffer.header.packetLen));
+ }
+ break;
+ case HGFS_TCP_CONN_RECV_DATA:
+ ret = HgfsTcpRecvMsg(tcpChannel.priv, &recvBuffer.data[0],
+ recvBuffer.header.packetLen);
+ if (ret > 0) {
+ ASSERT(ret == recvBuffer.header.packetLen);
+ *packetSize = ret;
+ *replyPacket = &recvBuffer.data[0];
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s: packet received. len: %d\n",
+ __FUNCTION__, ret));
+ recvBuffer.state = HGFS_TCP_CONN_RECV_HEADER;
+ }
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ if (ret < 0) {
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s: sock_recvmsg returns: %d\n",
+ __FUNCTION__, ret));
+ /* The connection is not lost for these three cases. */
+ if (ret != -EINTR && ret != -ERESTARTSYS && ret != -EAGAIN) {
+ recvBuffer.state = HGFS_TCP_CONN_RECV_HEADER;
+ tcpChannel.status = HGFS_CHANNEL_DISCONNECTED;
+ }
+ }
+
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTcpChannelSendAsync --
+ *
+ * Send the request via TCP channel. Add the header before sending.
+ *
+ * Results:
+ * 0 on success, negative error on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsTcpChannelSendAsync(HgfsReq *req) // IN: request to send
+{
+ HgfsTcpHeader sockHeader;
+ struct socket *socket;
+ mm_segment_t fs;
+ struct msghdr msg;
+ struct iovec iov[2];
+ int result;
+
+ ASSERT(req);
+ compat_mutex_lock(&tcpChannel.connLock);
+ if (tcpChannel.status != HGFS_CHANNEL_CONNECTED) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: Connection lost\n", __FUNCTION__));
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return -ENOTCONN;
+ }
+
+ socket = tcpChannel.priv;
+ memset(&msg, 0, sizeof msg);
+ sockHeader.version = HGFS_TCP_VERSION1;
+ sockHeader.packetLen = req->payloadSize;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 2;
+
+ iov[0].iov_base = &sockHeader;
+ iov[0].iov_len = sizeof sockHeader;
+ iov[1].iov_base = HGFS_REQ_PAYLOAD(req);
+ iov[1].iov_len = req->payloadSize;
+
+ /* get_fs/set_fs give us more privilidges so that we are able to call
+ sock_sendmsg from kernel. */
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ result = sock_sendmsg(socket, &msg, req->payloadSize);
+ set_fs(fs);
+
+ if (result < 0) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: sendmsg, err: %d.\n",
+ __FUNCTION__, result));
+ tcpChannel.status = HGFS_CHANNEL_DISCONNECTED;
+ } else {
+ LOG(8, ("VMware hgfs: %s: sendmsg, bytes sent: %d.\n",
+ __FUNCTION__, result));
+ ASSERT(result == req->payloadSize + sizeof sockHeader);
+ req->state = HGFS_REQ_STATE_SUBMITTED;
+ result = 0;
+ }
+
+ compat_mutex_unlock(&tcpChannel.connLock);
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTcpChannelExit --
+ *
+ * Tear down the channel and close TCP connection.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HgfsTcpChannelExit(void)
+{
+ compat_mutex_lock(&tcpChannel.connLock);
+ if (tcpChannel.priv != NULL) {
+ sock_release(tcpChannel.priv);
+ tcpChannel.priv = NULL;
+ }
+ tcpChannel.status = HGFS_CHANNEL_UNINITIALIZED;
+ compat_mutex_unlock(&tcpChannel.connLock);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTcpChannelInit --
+ *
+ * Initialize TCP channel and open the connection.
+ *
+ * Results:
+ * TRUE on success, otherwise FALSE.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+HgfsTcpChannelInit(void)
+{
+ tcpChannel.name = "tcp";
+ tcpChannel.ops.open = HgfsTcpChannelOpen;
+ tcpChannel.ops.close = HgfsTcpChannelClose;
+ tcpChannel.ops.send = HgfsTcpChannelSendAsync;
+ tcpChannel.ops.recv = HgfsTcpChannelRecvAsync;
+ tcpChannel.ops.exit = HgfsTcpChannelExit;
+ tcpChannel.priv = NULL;
+ compat_mutex_init(&tcpChannel.connLock);
+
+ /* Initialize hgfsConn. */
+ memset(&recvBuffer, 0, sizeof recvBuffer);
+ recvBuffer.state = HGFS_TCP_CONN_RECV_HEADER;
+ tcpChannel.status = HGFS_CHANNEL_DISCONNECTED;
+
+ if (!HOST_IP) {/* HOST_IP is defined in module.c. */
+ return FALSE;
+ }
+
+ return TRUE;
+}
/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
*********************************************************/
/*
- * backdoorInt.h --
+ * tcp.h --
*
- * Internal function prototypes for the real backdoor work.
+ * Tcp channel implementation.
*/
-void BackdoorHbIn(Backdoor_proto_hb *bp);
-void BackdoorHbOut(Backdoor_proto_hb *bp);
+#ifndef _HGFS_DRIVER_TCP_H_
+#define _HGFS_DRIVER_TCP_H_
+
+#include "transport.h"
+
+Bool HgfsTcpChannelInit(void);
+
+extern HgfsTransportChannel tcpChannel;
+
+#endif // _HGFS_DRIVER_TCP_H_
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * transport.c --
+ *
+ * This file handles the transport mechanisms available for HGFS.
+ * This acts as a glue between the HGFS filesystem driver and the
+ * actual transport channels (backdoor, tcp, vsock, ...).
+ *
+ * The sends happen in the process context, where as a kernel thread
+ * handles the asynchronous replies. A queue of pending replies is
+ * maintained and is protected by a spinlock. The channel opens and close
+ * is protected by a mutex.
+ */
+
+/* Must come before any kernel header file. */
+#include "driver-config.h"
+
+#include <linux/errno.h>
+#include "compat_kthread.h"
+#include "compat_list.h"
+#include "compat_mutex.h"
+#include "compat_sched.h"
+#include "compat_spinlock.h"
+#include "compat_version.h"
+
+/* Must be included after semaphore.h. */
+#include <linux/timer.h>
+/* Must be included after sched.h. */
+#include <linux/smp_lock.h>
+
+#include "bdhandler.h"
+#include "hgfsDevLinux.h"
+#include "hgfsProto.h"
+#include "module.h"
+#include "request.h"
+#include "tcp.h"
+#include "transport.h"
+#include "vm_assert.h"
+
+COMPAT_KTHREAD_DECLARE_STOP_INFO();
+static HgfsTransportChannel *hgfsChannel; /* Current active channel. */
+static compat_mutex_t hgfsChannelLock; /* Lock to protect hgfsChannel. */
+static struct task_struct *hgfsRecvThread; /* Recv thread. */
+static struct list_head hgfsRepPending; /* Reply pending queue. */
+static spinlock_t hgfsRepQueueLock; /* Reply pending queue lock. */
+
+#define HgfsRequestId(req) ((HgfsRequest *)req)->id
+
+
+/*
+ * Private function implementations.
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportProcessPacket --
+ *
+ * Helper function to process received packets, used by the transport
+ * handler thread.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HgfsTransportProcessPacket(char *receivedPacket, //IN: received packet
+ size_t receivedSize) //IN: packet size
+{
+ struct list_head *cur, *next;
+ HgfsHandle id;
+ Bool found = FALSE;
+
+ /* Got the reply. */
+
+ ASSERT(receivedPacket != NULL && receivedSize > 0);
+ id = HgfsRequestId(receivedPacket);
+ LOG(8, ("VMware hgfs: %s entered.\n", __FUNCTION__));
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: req id: %d\n", __FUNCTION__, id));
+ /*
+ * Search through hgfsRepPending queue for the matching id and wake up
+ * the associated waiting process. Delete the req from the queue.
+ */
+ spin_lock(&hgfsRepQueueLock);
+ list_for_each_safe(cur, next, &hgfsRepPending) {
+ HgfsReq *req;
+ req = list_entry(cur, HgfsReq, list);
+ if (req->id == id) {
+ ASSERT(req->state == HGFS_REQ_STATE_SUBMITTED);
+ HgfsCompleteReq(req, receivedPacket, receivedSize);
+ found = TRUE;
+ break;
+ }
+ }
+ spin_unlock(&hgfsRepQueueLock);
+
+ if (!found) {
+ LOG(4, ("VMware hgfs: %s: No matching id, dropping reply\n",
+ __FUNCTION__));
+ }
+ LOG(8, ("VMware hgfs: %s exited.\n", __FUNCTION__));
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportReceiveHandler --
+ *
+ * Function run in background thread and wait on the data in the
+ * connected channel.
+ *
+ * Results:
+ * Always returns zero.
+ *
+ * Side effects:
+ * Can be many.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsTransportReceiveHandler(void *data) // IN: Hgfs connection data
+{
+ HgfsTransportChannel *channel = (HgfsTransportChannel *)data;
+ char *receivedPacket = NULL;
+ size_t receivedSize = 0;
+ int ret = 0;
+
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: thread started\n", __FUNCTION__));
+ ASSERT(data);
+
+ compat_set_freezable();
+ for (;;) {
+ /* Kill yourself if told so. */
+ if (compat_kthread_should_stop()) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: told to exit\n", __FUNCTION__));
+ break;
+ }
+
+ /* Check for suspend. */
+ if (compat_try_to_freeze()) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: closing transport after resume."
+ "\n", __FUNCTION__));
+ /* Close the transport. */
+ channel->ops.close();
+ continue;
+ }
+
+ /* Waiting on the data, may be blocked. */
+ ASSERT(channel->ops.recv != NULL);
+ ret = channel->ops.recv(&receivedPacket, &receivedSize);
+ if (ret < 0) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: recv error. Return %d\n",
+ __FUNCTION__, ret));
+ if (!channel->ops.open()) {
+ /* We are unable to reconnect to the server, exit the thread. */
+ break;
+ }
+ } else if (ret == 0) {
+ continue; /* No complete packet received. */
+ }
+
+ /* Process the packet recieved. */
+ HgfsTransportProcessPacket(receivedPacket, receivedSize);
+ }
+
+ hgfsRecvThread = NULL;
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportStopReceivingThread --
+ *
+ * Helper function to stop transport handler thread.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HgfsTransportStopReceivingThread(void)
+{
+ if (hgfsRecvThread) {
+ /* Wake up socket by sending signal. */
+ force_sig(SIGKILL, hgfsRecvThread);
+ compat_kthread_stop(hgfsRecvThread);
+ hgfsRecvThread = NULL;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsCompleteChannelInitialization --
+ *
+ * Helper function to complete channel initialization. Starts the
+ * receive thread, if needed, and opens the channel so it is ready.
+ *
+ * Results:
+ * TRUE in case of success, FALSE otherwise.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Bool
+HgfsCompleteChannelInitialization(HgfsTransportChannel *channel) // IN: channel
+{
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: %s channel created.\n",
+ __func__, channel->name));
+
+ hgfsChannel = channel;
+
+ if (hgfsChannel != &bdChannel) { /* No recv thread for backdoor channel. */
+ hgfsRecvThread = compat_kthread_run(HgfsTransportReceiveHandler,
+ hgfsChannel, "vmhgfs-rep");
+ if (IS_ERR(hgfsRecvThread)) {
+ LOG(4, (KERN_ERR "VMware hgfs: %s: failed to create receiving thread\n",
+ __func__));
+ goto err_exit;
+ }
+ }
+
+ if (!hgfsChannel->ops.open()) {
+ LOG(4, (KERN_ERR "VMware hgfs: %s: failed to start %s channel.\n",
+ __func__, hgfsChannel->name));
+ goto err_stop_thread;
+ }
+
+ return TRUE;
+
+err_stop_thread:
+ HgfsTransportStopReceivingThread();
+err_exit:
+ hgfsRecvThread = NULL;
+ hgfsChannel->ops.exit();
+ hgfsChannel = NULL;
+
+ return FALSE;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportSetupNewChannel --
+ *
+ * Find a new workable channel.
+ *
+ * Results:
+ * TRUE on success, otherwise FALSE.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+HgfsTransportSetupNewChannel(void)
+{
+ ASSERT(hgfsChannel == NULL);
+ ASSERT(hgfsRecvThread == NULL);
+
+ if (HgfsTcpChannelInit() &&
+ HgfsCompleteChannelInitialization(&tcpChannel)) {
+ return TRUE;
+ }
+
+ if (HgfsBdChannelInit() &&
+ HgfsCompleteChannelInitialization(&bdChannel)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportStopCurrentChannel --
+ *
+ * Teardown current channel and stop current receive thread.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HgfsTransportStopCurrentChannel(void)
+{
+ HgfsTransportStopReceivingThread();
+ if (!hgfsChannel) {
+ return;
+ }
+ hgfsChannel->ops.exit();
+ hgfsChannel = NULL;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportChannelFailover --
+ *
+ * Called when current channel doesn't work. Find a new channel
+ * for transport.
+ *
+ * Results:
+ * TRUE on success, otherwise FALSE;
+ *
+ * Side effects:
+ * Teardown current opened channel and the receive thread, set up
+ * new channel and new receive thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Bool
+HgfsTransportChannelFailover(void) {
+ Bool ret = FALSE;
+ HgfsTransportStopCurrentChannel();
+ ret = HgfsTransportSetupNewChannel();
+ LOG(8, ("VMware hgfs: %s result: %s.\n", __FUNCTION__,
+ ret ? "TRUE" : "FALSE"));
+ return ret;
+}
+
+
+/*
+ * Public function implementations.
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransporAddPendingRequest --
+ *
+ * Adds a request to the hgfsRepPending queue.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HgfsTransportAddPendingRequest(HgfsReq *req) // IN: Request to add
+{
+ ASSERT(req);
+
+ spin_lock(&hgfsRepQueueLock);
+ list_add_tail(&req->list, &hgfsRepPending);
+ spin_unlock(&hgfsRepQueueLock);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportRemovePendingRequest --
+ *
+ * Dequeues the request from the hgfsRepPending queue.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HgfsTransportRemovePendingRequest(HgfsReq *req) // IN: Request to dequeue
+{
+ ASSERT(req);
+
+ spin_lock(&hgfsRepQueueLock);
+ list_del_init(&req->list);
+ spin_unlock(&hgfsRepQueueLock);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportSendRequest --
+ *
+ * Sends the request via channel communication.
+ *
+ * Results:
+ * Zero on success, non-zero error on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+HgfsTransportSendRequest(HgfsReq *req) // IN: Request to send
+{
+ int ret;
+ ASSERT(req);
+ ASSERT(req->state == HGFS_REQ_STATE_UNSENT);
+ ASSERT(req->payloadSize <= HGFS_PACKET_MAX);
+
+ compat_mutex_lock(&hgfsChannelLock);
+
+ /* Try opening the channel. */
+ if (!hgfsChannel && !HgfsTransportSetupNewChannel()) {
+ ret = -EPROTO;
+ goto out;
+ }
+ ASSERT(hgfsChannel->ops.send);
+
+ HgfsTransportAddPendingRequest(req);
+
+ while ((ret = hgfsChannel->ops.send(req)) != 0) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: send failed. Return %d\n",
+ __FUNCTION__, ret));
+ if (!hgfsChannel->ops.open() && !HgfsTransportChannelFailover()) {
+ /* Can't establish a working channel, just report error. */
+ HgfsTransportRemovePendingRequest(req);
+ ret = -EIO;
+ goto out;
+ }
+ }
+
+ ASSERT(req->state == HGFS_REQ_STATE_COMPLETED ||
+ req->state == HGFS_REQ_STATE_SUBMITTED);
+
+out:
+ compat_mutex_unlock(&hgfsChannelLock);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportInit --
+ *
+ * Initialize the transport.
+ *
+ * Starts the reply thread, for handling incoming packets on the
+ * connected socket.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+HgfsTransportInit(void)
+{
+ INIT_LIST_HEAD(&hgfsRepPending);
+ spin_lock_init(&hgfsRepQueueLock);
+ compat_mutex_init(&hgfsChannelLock);
+
+ hgfsChannel = NULL;
+ hgfsRecvThread = NULL;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsTransportExit --
+ *
+ * Teardown the transport.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Cleans up everything, frees queues, closes channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+HgfsTransportExit(void)
+{
+ LOG(8, ("VMware hgfs: %s entered.\n", __FUNCTION__));
+ compat_mutex_lock(&hgfsChannelLock);
+ HgfsTransportStopCurrentChannel();
+ compat_mutex_unlock(&hgfsChannelLock);
+
+ ASSERT(list_empty(&hgfsRepPending));
+ LOG(8, ("VMware hgfs: %s exited.\n", __FUNCTION__));
+}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * transport.h --
+ */
+
+#ifndef _HGFS_DRIVER_TRANSPORT_H_
+#define _HGFS_DRIVER_TRANSPORT_H_
+
+#include "request.h"
+#include "compat_mutex.h"
+
+/*
+ * There are the operations a channel should implement.
+ */
+typedef struct HgfsTransportChannelOps {
+ Bool (*open)(void);
+ void (*close)(void);
+ int (*send)(HgfsReq *);
+ int (*recv)(char **, size_t *);
+ void (*exit)(void);
+} HgfsTransportChannelOps;
+
+typedef enum {
+ HGFS_CHANNEL_UNINITIALIZED,
+ HGFS_CHANNEL_DISCONNECTED,
+ HGFS_CHANNEL_CONNECTED,
+} HgfsChannelStatus;
+
+typedef struct HgfsTransportChannel {
+ const char *name; /* Channel name. */
+ HgfsTransportChannelOps ops; /* Channel ops. */
+ HgfsChannelStatus status; /* Connection status. */
+ void *priv; /* Channel private data. */
+ compat_mutex_t connLock; /* Protect _this_ struct. */
+} HgfsTransportChannel;
+
+/* Public functions (with respect to the entire module). */
+void HgfsTransportInit(void);
+void HgfsTransportExit(void);
+int HgfsTransportSendRequest(HgfsReq *req);
+
+#endif // _HGFS_DRIVER_TRANSPORT_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_assert.h --
- *
- * The basic assertion facility for all VMware code.
- *
- * For proper use, see
- * http://vmweb.vmware.com/~mts/WebSite/guide/programming/asserts.html
- */
-
-#ifndef _VM_ASSERT_H_
-#define _VM_ASSERT_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-// XXX not necessary except some places include vm_assert.h improperly
-#include "vm_basic_types.h"
-#include "vm_basic_defs.h"
-
-
-/*
- * XXX old file code
- */
-
-#ifdef FILECODEINT
-#error "Don't define FILECODEINT. It is obsolete."
-#endif
-#ifdef FILECODE
-#error "Don't define FILECODE. It is obsolete."
-#endif
-
-
-/*
- * Panic and log functions
- */
-
-EXTERN void Log(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN void Warning(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2);
-
-EXTERN void LogThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-EXTERN void WarningThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-
-/* DB family: messages which are parsed by logfile database system */
-#define WarningDB Warning
-#define LogDB Log
-#define WarningThrottledDB WarningThrottled
-#define LogThrottledDB LogThrottled
-
-
-/*
- * Stress testing: redefine ASSERT_IFNOT() to taste
- */
-
-#ifndef ASSERT_IFNOT
- /*
- * PR 271512: When compiling with gcc, catch assignments inside an ASSERT.
- *
- * 'UNLIKELY' is defined with __builtin_expect, which does not warn when passed an
- * assignment (gcc bug 36050).
- * To get around this, we put 'cond' in an 'if' statement and make sure it never gets
- * executed by putting that inside of 'if (0)'.
- * We use gcc's statement expression syntax to make ASSERT an expression because some
- * code uses it that way.
- *
- * Since statement expression syntax is a gcc extension and since it's not clear if
- * this is a problem with other compilers, the ASSERT definition was not changed for
- * them. Using a bare 'cond' with the ternary operator may provide a solution.
- */
- #ifdef __GNUC__
- #define ASSERT_IFNOT(cond, panic) \
- ({if (UNLIKELY(!(cond))) { panic; if (0) { if (cond) { ; } } } (void)0;})
- #else
- #define ASSERT_IFNOT(cond, panic) \
- (UNLIKELY(!(cond)) ? (panic) : (void)0)
- #endif
-#endif
-
-
-/*
- * Assert, panic, and log macros
- *
- * Some of these are redefined below undef !VMX86_DEBUG.
- * ASSERT() is special cased because of interaction with Windows DDK.
- */
-
-#if defined VMX86_DEBUG || defined ASSERT_ALWAYS_AVAILABLE
-#undef ASSERT
-#define ASSERT(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertAssert))
-#endif
-#define ASSERT_BUG(bug, cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC_BUG(bug, AssertAssert))
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ASSERT_BUG(bug, cond)
-
-#define PANIC() _ASSERT_PANIC(AssertPanic)
-#define PANIC_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertPanic)
-
-#define ASSERT_NOT_IMPLEMENTED(cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED())
-#define ASSERT_NOT_IMPLEMENTED_BUG(bug, cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED_BUG(bug))
-
-#define NOT_IMPLEMENTED() _ASSERT_PANIC(AssertNotImplemented)
-#define NOT_IMPLEMENTED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotImplemented)
-
-#define NOT_REACHED() _ASSERT_PANIC(AssertNotReached)
-#define NOT_REACHED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotReached)
-
-#define ASSERT_MEM_ALLOC(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertMemAlloc))
-
-#ifdef VMX86_DEVEL
- #define ASSERT_LENGTH(real, expected) \
- ASSERT_IFNOT((real) == (expected), \
- Panic(AssertLengthFmt, __FILE__, __LINE__, real, expected))
-#else
- #define ASSERT_LENGTH(real, expected) ASSERT((real) == (expected))
-#endif
-
-#ifdef VMX86_DEVEL
- #define ASSERT_DEVEL(cond) ASSERT(cond)
-#else
- #define ASSERT_DEVEL(cond) ((void) 0)
-#endif
-
-#define ASSERT_NO_INTERRUPTS() ASSERT(!INTERRUPTS_ENABLED())
-#define ASSERT_HAS_INTERRUPTS() ASSERT(INTERRUPTS_ENABLED())
-
-#define ASSERT_LOG_UNEXPECTED(bug, cond) \
- (UNLIKELY(!(cond)) ? LOG_UNEXPECTED(bug) : 0)
-#ifdef VMX86_DEVEL
- #define LOG_UNEXPECTED(bug) \
- Warning(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#else
- #define LOG_UNEXPECTED(bug) \
- Log(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#endif
-
-#define ASSERT_NOT_TESTED(cond) (UNLIKELY(!(cond)) ? NOT_TESTED() : 0)
-#ifdef VMX86_DEVEL
- #define NOT_TESTED() Warning(AssertNotTestedFmt, __FILE__, __LINE__)
-#else
- #define NOT_TESTED() Log(AssertNotTestedFmt, __FILE__, __LINE__)
-#endif
-
-#define NOT_TESTED_ONCE() \
- do { \
- static Bool alreadyPrinted = FALSE; \
- if (UNLIKELY(!alreadyPrinted)) { \
- alreadyPrinted = TRUE; \
- NOT_TESTED(); \
- } \
- } while (0)
-
-#define NOT_TESTED_1024() \
- do { \
- static uint16 count = 0; \
- if (UNLIKELY(count == 0)) { NOT_TESTED(); } \
- count = (count + 1) & 1023; \
- } while (0)
-
-#define LOG_ONCE(_s) \
- do { \
- static Bool logged = FALSE; \
- if (!logged) { \
- Log _s; \
- logged = TRUE; \
- } \
- } while (0)
-
-
-/*
- * Redefine macros that are only in debug versions
- */
-
-#if !defined VMX86_DEBUG && !defined ASSERT_ALWAYS_AVAILABLE // {
-
-#undef ASSERT
-#define ASSERT(cond) ((void) 0)
-
-#undef ASSERT_BUG_DEBUGONLY
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ((void) 0)
-
-#undef ASSERT_LENGTH
-#define ASSERT_LENGTH(real, expected) ((void) 0)
-
-/*
- * Expand NOT_REACHED() as appropriate for each situation.
- *
- * Mainly, we want the compiler to infer the same control-flow
- * information as it would from Panic(). Otherwise, different
- * compilation options will lead to different control-flow-derived
- * errors, causing some make targets to fail while others succeed.
- *
- * VC++ has the __assume() built-in function which we don't trust
- * (see bug 43485); gcc has no such construct; we just panic in
- * userlevel code. The monitor doesn't want to pay the size penalty
- * (measured at 212 bytes for the release vmm for a minimal infinite
- * loop; panic would cost even more) so it does without and lives
- * with the inconsistency.
- */
-
-#ifdef VMM
-#undef NOT_REACHED
-#define NOT_REACHED() ((void) 0)
-#else
-// keep debug definition
-#endif
-
-#undef ASSERT_LOG_UNEXPECTED
-#define ASSERT_LOG_UNEXPECTED(bug, cond) ((void) 0)
-
-#undef LOG_UNEXPECTED
-#define LOG_UNEXPECTED(bug) ((void) 0)
-
-#undef ASSERT_NOT_TESTED
-#define ASSERT_NOT_TESTED(cond) ((void) 0)
-#undef NOT_TESTED
-#define NOT_TESTED() ((void) 0)
-#undef NOT_TESTED_ONCE
-#define NOT_TESTED_ONCE() ((void) 0)
-#undef NOT_TESTED_1024
-#define NOT_TESTED_1024() ((void) 0)
-
-#endif // !VMX86_DEBUG }
-
-
-/*
- * Compile-time assertions.
- *
- * ASSERT_ON_COMPILE does not use the common
- * switch (0) { case 0: case (e): ; } trick because some compilers (e.g. MSVC)
- * generate code for it.
- *
- * The implementation uses both enum and typedef because the typedef alone is
- * insufficient; gcc allows arrays to be declared with non-constant expressions
- * (even in typedefs, where it makes no sense).
- */
-
-#define ASSERT_ON_COMPILE(e) \
- do { \
- enum { AssertOnCompileMisused = ((e) ? 1 : -1) }; \
- typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \
- } while (0)
-
-
-/*
- * To put an ASSERT_ON_COMPILE() outside a function, wrap it
- * in MY_ASSERTS(). The first parameter must be unique in
- * each .c file where it appears. For example,
- *
- * MY_ASSERTS(FS3_INT,
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLock) == 128);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLockReserved) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskBlock) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(Hardware_DMIUUID) == 16);
- * )
- *
- * Caution: ASSERT() within MY_ASSERTS() is silently ignored.
- * The same goes for anything else not evaluated at compile time.
- */
-
-#define MY_ASSERTS(name, assertions) \
- static INLINE void name(void) { \
- assertions \
- }
-
-
-/*
- * Internal macros, functions, and strings
- *
- * The monitor wants to save space at call sites, so it has specialized
- * functions for each situation. User level wants to save on implementation
- * so it uses generic functions.
- */
-
-#if !defined VMM || defined MONITOR_APP // {
-
-#define _ASSERT_PANIC(name) \
- Panic(_##name##Fmt "\n", __FILE__, __LINE__)
-#define _ASSERT_PANIC_BUG(bug, name) \
- Panic(_##name##Fmt " bugNr=%d\n", __FILE__, __LINE__, bug)
-
-#define AssertLengthFmt _AssertLengthFmt
-#define AssertUnexpectedFmt _AssertUnexpectedFmt
-#define AssertNotTestedFmt _AssertNotTestedFmt
-
-#endif // }
-
-// these don't have newline so a bug can be tacked on
-#define _AssertPanicFmt "PANIC %s:%d"
-#define _AssertAssertFmt "ASSERT %s:%d"
-#define _AssertNotImplementedFmt "NOT_IMPLEMENTED %s:%d"
-#define _AssertNotReachedFmt "NOT_REACHED %s:%d"
-#define _AssertMemAllocFmt "MEM_ALLOC %s:%d"
-
-// these are complete formats with newline
-#define _AssertLengthFmt "LENGTH %s:%d r=%#x e=%#x\n"
-#define _AssertUnexpectedFmt "UNEXPECTED %s:%d bugNr=%d\n"
-#define _AssertNotTestedFmt "NOT_TESTED %s:%d\n"
-
-#endif /* ifndef _VM_ASSERT_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_asm.h
- *
- * Basic asm macros
- */
-
-#ifndef _VM_BASIC_ASM_H_
-#define _VM_BASIC_ASM_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-#include "x86cpuid.h"
-
-#ifdef VM_X86_64
-#include "vm_basic_asm_x86_64.h"
-#else
-#include "vm_basic_asm_x86.h"
-#endif
-
-
-/*
- * x86-64 windows doesn't support inline asm so we have to use these
- * intrinsic functions defined in the compiler. Not all of these are well
- * documented. There is an array in the compiler dll (c1.dll) which has
- * an array of the names of all the intrinsics minus the leading
- * underscore. Searching around in the ntddk.h file can also be helpful.
- *
- * The declarations for the intrinsic functions were taken from the DDK.
- * Our declarations must match the ddk's otherwise the 64-bit c++ compiler
- * will complain about second linkage of the intrinsic functions.
- * We define the intrinsic using the basic types corresponding to the
- * Windows typedefs. This avoids having to include windows header files
- * to get to the windows types.
- */
-#ifdef _MSC_VER
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * It seems x86 & x86-64 windows still implements these intrinsic
- * functions. The documentation for the x86-64 suggest the
- * __inbyte/__outbyte intrinsics eventhough the _in/_out work fine and
- * __inbyte/__outbyte aren't supported on x86.
- */
-int _inp(unsigned short);
-unsigned short _inpw(unsigned short);
-unsigned long _inpd(unsigned short);
-
-int _outp(unsigned short, int);
-unsigned short _outpw(unsigned short, unsigned short);
-unsigned long _outpd(uint16, unsigned long);
-#pragma intrinsic(_inp, _inpw, _inpd, _outp, _outpw, _outpw, _outpd)
-void _ReadWriteBarrier(void);
-#pragma intrinsic(_ReadWriteBarrier)
-
-#ifdef VM_X86_64
-/*
- * intrinsic functions only supported by x86-64 windows as of 2k3sp1
- */
-void __cpuid(unsigned int*, unsigned int);
-unsigned __int64 __rdtsc(void);
-void __stosw(unsigned short*, unsigned short, size_t);
-void __stosd(unsigned long*, unsigned long, size_t);
-#pragma intrinsic(__cpuid, __rdtsc, __stosw, __stosd)
-
-/*
- * intrinsic functions supported by x86-64 windows and newer x86
- * compilers (13.01.2035 for _BitScanForward).
- */
-unsigned char _BitScanForward(unsigned long*, unsigned long);
-void _mm_pause(void);
-#pragma intrinsic(_BitScanForward, _mm_pause)
-#endif /* VM_X86_64 */
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _MSC_VER */
-
-
-#ifdef __GNUC__ // {
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * volatile because reading from port can modify the state of the underlying
- * hardware.
- *
- * Note: The undocumented %z construct doesn't work (internal compiler error)
- * with gcc-2.95.1
- */
-
-#define __GCC_IN(s, type, name) \
-static INLINE type \
-name(uint16 port) \
-{ \
- type val; \
- \
- __asm__ __volatile__( \
- "in" #s " %w1, %0" \
- : "=a" (val) \
- : "Nd" (port) \
- ); \
- \
- return val; \
-}
-
-__GCC_IN(b, uint8, INB)
-__GCC_IN(w, uint16, INW)
-__GCC_IN(l, uint32, IN32)
-
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * Note: The undocumented %z construct doesn't work (internal compiler error)
- * with gcc-2.95.1
- */
-
-#define __GCC_OUT(s, s2, port, val) do { \
- __asm__( \
- "out" #s " %" #s2 "1, %w0" \
- : \
- : "Nd" (port), "a" (val) \
- ); \
-} while (0)
-
-#define OUTB(port, val) __GCC_OUT(b, b, port, val)
-#define OUTW(port, val) __GCC_OUT(w, w, port, val)
-#define OUT32(port, val) __GCC_OUT(l, , port, val)
-
-
-#define GET_CURRENT_EIP(_eip) \
- __asm__ __volatile("call 0\n\tpopl %0" : "=r" (_eip): );
-
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * Need __volatile__ and "memory" since CPUID has a synchronizing effect.
- * The CPUID may also change at runtime (APIC flag, etc).
- *
- */
-
-static INLINE void
-__GET_CPUID(int eax, // IN
- CPUIDRegs *regs) // OUT
-{
- __asm__ __volatile__(
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (regs->eax), "=&rm" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#else
- "cpuid"
- : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#endif
- : "a" (eax)
- : "memory"
- );
-}
-
-static INLINE void
-__GET_CPUID2(int eax, // IN
- int ecx, // IN
- CPUIDRegs *regs) // OUT
-{
- __asm__ __volatile__(
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (regs->eax), "=&rm" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#else
- "cpuid"
- : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#endif
- : "a" (eax), "c" (ecx)
- : "memory"
- );
-}
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID(int eax) // IN
-{
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx)
- : "a" (eax)
- : "memory", "%ecx", "%edx"
- );
-#else
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax)
- : "a" (eax)
- : "memory", "%ebx", "%ecx", "%edx"
- );
-#endif
-
- return eax;
-}
-
-static INLINE uint32
-__GET_EBX_FROM_CPUID(int eax) // IN
-{
- uint32 ebx;
-
- __asm__ __volatile__(
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx)
-#else
- "cpuid"
- : "=a" (eax), "=b" (ebx)
-#endif
- : "a" (eax)
- : "memory", "%ecx", "%edx"
- );
-
- return ebx;
-}
-
-static INLINE uint32
-__GET_ECX_FROM_CPUID(int eax) // IN
-{
- uint32 ecx;
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx), "=c" (ecx)
- : "a" (eax)
- : "memory", "%edx"
- );
-#else
-
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax), "=c" (ecx)
- : "a" (eax)
- : "memory", "%ebx", "%edx"
- );
-#endif
-
- return ecx;
-}
-
-static INLINE uint32
-__GET_EDX_FROM_CPUID(int eax) // IN
-{
- uint32 edx;
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx), "=d" (edx)
- : "a" (eax)
- : "memory", "%ecx"
- );
-#else
-
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax), "=d" (edx)
- : "a" (eax)
- : "memory", "%ebx", "%ecx"
- );
-#endif
-
- return edx;
-}
-
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID4(int ecx) // IN
-{
- uint32 eax;
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx), "=c" (ecx)
- : "a" (4), "c" (ecx)
- : "memory", "%edx"
- );
-#else
-
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax), "=c" (ecx)
- : "a" (4), "c" (ecx)
- : "memory", "%ebx", "%edx"
- );
-#endif
-
- return eax;
-}
-
-#elif defined(_MSC_VER) // } {
-static INLINE uint8
-INB(uint16 port)
-{
- return (uint8)_inp(port);
-}
-static INLINE void
-OUTB(uint16 port, uint8 value)
-{
- _outp(port, value);
-}
-static INLINE uint16
-INW(uint16 port)
-{
- return _inpw(port);
-}
-static INLINE void
-OUTW(uint16 port, uint16 value)
-{
- _outpw(port, value);
-}
-static INLINE uint32
-IN32(uint16 port)
-{
- return _inpd(port);
-}
-static INLINE void
-OUT32(uint16 port, uint32 value)
-{
- _outpd(port, value);
-}
-
-#ifndef VM_X86_64
-#ifdef NEAR
-#undef NEAR
-#endif
-
-#define GET_CURRENT_EIP(_eip) do { \
- __asm call NEAR PTR $+5 \
- __asm pop eax \
- __asm mov _eip, eax \
-} while (0)
-#endif
-
-static INLINE void
-__GET_CPUID(int input, CPUIDRegs *regs)
-{
-#ifdef VM_X86_64
- __cpuid((unsigned int *)regs, input);
-#else
- __asm push esi
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm mov esi, regs
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov 0x0[esi], eax
- __asm mov 0x4[esi], ebx
- __asm mov 0x8[esi], ecx
- __asm mov 0xC[esi], edx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
- __asm pop esi
-#endif
-}
-
-#ifdef VM_X86_64
-
-/*
- * No inline assembly in Win64. Implemented in bora/lib/user in
- * cpuidMasm64.asm.
- */
-
-extern void
-__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs);
-
-#else // VM_X86_64
-
-static INLINE void
-__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs)
-{
- __asm push esi
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, inputEax
- __asm mov ecx, inputEcx
- __asm mov esi, regs
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov 0x0[esi], eax
- __asm mov 0x4[esi], ebx
- __asm mov 0x8[esi], ecx
- __asm mov 0xC[esi], edx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
- __asm pop esi
-}
-#endif
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.eax;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, eax
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-static INLINE uint32
-__GET_EBX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.ebx;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, ebx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-static INLINE uint32
-__GET_ECX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.ecx;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, ecx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-static INLINE uint32
-__GET_EDX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.edx;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, edx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-#ifdef VM_X86_64
-
-/*
- * No inline assembly in Win64. Implemented in bora/lib/user in
- * cpuidMasm64.asm.
- */
-
-extern uint32
-__GET_EAX_FROM_CPUID4(int inputEcx);
-
-#else // VM_X86_64
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID4(int inputEcx)
-{
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, 4
- __asm mov ecx, inputEcx
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, eax
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-}
-
-#endif // VM_X86_64
-
-#else // }
-#error
-#endif
-
-#define CPUID_FOR_SIDE_EFFECTS() ((void)__GET_EAX_FROM_CPUID(0))
-
-static INLINE void
-__GET_CPUID4(int inputEcx, CPUIDRegs *regs)
-{
- __GET_CPUID2(4, inputEcx, regs);
-}
-
-/* The first parameter is used as an rvalue and then as an lvalue. */
-#define GET_CPUID(_ax, _bx, _cx, _dx) { \
- CPUIDRegs regs; \
- __GET_CPUID(_ax, ®s); \
- _ax = regs.eax; \
- _bx = regs.ebx; \
- _cx = regs.ecx; \
- _dx = regs.edx; \
-}
-
-
-/* Sequence recommended by Intel for the Pentium 4. */
-#define INTEL_MICROCODE_VERSION() ( \
- __SET_MSR(MSR_BIOS_SIGN_ID, 0), \
- __GET_EAX_FROM_CPUID(1), \
- __GET_MSR(MSR_BIOS_SIGN_ID))
-
-
-#ifdef _MSC_VER
-static INLINE int
-ffs(uint32 bitVector)
-{
- int idx;
- if (!bitVector) {
- return 0;
- }
-#ifdef VM_X86_64
- _BitScanForward((unsigned long*)&idx, (unsigned long)bitVector);
-#else
- __asm bsf eax, bitVector
- __asm mov idx, eax
-#endif
- return idx+1;
-}
-#endif
-
-#ifdef __GNUC__
-static INLINE void *
-uint16set(void *dst, uint16 val, size_t count)
-{
- int dummy0;
- int dummy1;
-
- __asm__ __volatile__("\t"
- "cld" "\n\t"
- "rep ; stosw" "\n"
- : "=c" (dummy0), "=D" (dummy1)
- : "0" (count), "1" (dst), "a" (val)
- : "memory", "cc"
- );
-
- return dst;
-}
-
-static INLINE void *
-uint32set(void *dst, uint32 val, size_t count)
-{
- int dummy0;
- int dummy1;
-
- __asm__ __volatile__("\t"
- "cld" "\n\t"
- "rep ; stosl" "\n"
- : "=c" (dummy0), "=D" (dummy1)
- : "0" (count), "1" (dst), "a" (val)
- : "memory", "cc"
- );
-
- return dst;
-}
-
-#elif defined(_MSC_VER)
-
-static INLINE void *
-uint16set(void *dst, uint16 val, size_t count)
-{
-#ifdef VM_X86_64
- __stosw((uint16*)dst, val, count);
-#else
- __asm { pushf;
- mov ax, val;
- mov ecx, count;
- mov edi, dst;
- cld;
- rep stosw;
- popf;
- }
-#endif
- return dst;
-}
-
-static INLINE void *
-uint32set(void *dst, uint32 val, size_t count)
-{
-#ifdef VM_X86_64
- __stosd((unsigned long*)dst, (unsigned long)val, count);
-#else
- __asm { pushf;
- mov eax, val;
- mov ecx, count;
- mov edi, dst;
- cld;
- rep stosd;
- popf;
- }
-#endif
- return dst;
-}
-
-#else
-#error "No compiler defined for uint*set"
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Bswap32 --
- *
- * Swap the 4 bytes of "v" as follows: 3210 -> 0123.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Bswap32(uint32 v) // IN
-{
-#ifdef __GNUC__ // {
- /* Checked against the Intel manual and GCC. --hpreg */
- __asm__(
- "bswap %0"
- : "=r" (v)
- : "0" (v)
- );
- return v;
-#else // } {
- return (v >> 24)
- | ((v >> 8) & 0xFF00)
- | ((v & 0xFF00) << 8)
- | (v << 24) ;
-#endif // }
-}
-#define Bswap Bswap32
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Bswap64 --
- *
- * Swap the 8 bytes of "v" as follows: 76543210 -> 01234567.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Bswap64(uint64 v) // IN
-{
- return ((uint64)Bswap((uint32)v) << 32) | Bswap((uint32)(v >> 32));
-}
-
-
-#ifdef __GNUC__ // {
-/*
- * COMPILER_MEM_BARRIER prevents the compiler from re-ordering memory
- * references accross the barrier. NOTE: It does not generate any
- * instruction, so the CPU is free to do whatever it wants to...
- */
-#define COMPILER_MEM_BARRIER() __asm__ __volatile__ ("": : :"memory")
-#elif defined(_MSC_VER) // } {
-#define COMPILER_MEM_BARRIER() _ReadWriteBarrier()
-#endif // }
-
-
-/*
- * PAUSE is a P4 instruction that improves spinlock power+performance;
- * on non-P4 IA32 systems, the encoding is interpreted as a REPZ-NOP.
- * Use volatile to avoid NOP removal.
- */
-static INLINE void
-PAUSE(void)
-#ifdef __GNUC__
-{
- __asm__ __volatile__( "pause" :);
-}
-#elif defined(_MSC_VER)
-#ifdef VM_X86_64
-{
- _mm_pause();
-}
-#else /* VM_X86_64 */
-#pragma warning( disable : 4035)
-{
- __asm _emit 0xf3 __asm _emit 0x90
-}
-#pragma warning (default: 4035)
-#endif /* VM_X86_64 */
-#else /* __GNUC__ */
-#error No compiler defined for PAUSE
-#endif
-
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * volatile because the tsc always changes without the compiler knowing it.
- */
-static INLINE uint64
-RDTSC(void)
-#ifdef __GNUC__
-{
-#ifdef VM_X86_64
- uint64 tscLow;
- uint64 tscHigh;
-
- __asm__ __volatile__(
- "rdtsc"
- : "=a" (tscLow), "=d" (tscHigh)
- );
-
- return tscHigh << 32 | tscLow;
-#else
- uint64 tim;
-
- __asm__ __volatile__(
- "rdtsc"
- : "=A" (tim)
- );
-
- return tim;
-#endif
-}
-#elif defined(_MSC_VER)
-#ifdef VM_X86_64
-{
- return __rdtsc();
-}
-#else
-#pragma warning( disable : 4035)
-{
- __asm _emit 0x0f __asm _emit 0x31
-}
-#pragma warning (default: 4035)
-#endif /* VM_X86_64 */
-#else /* __GNUC__ */
-#error No compiler defined for RDTSC
-#endif /* __GNUC__ */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DEBUGBREAK --
- *
- * Does an int3 for MSVC / GCC. This is a macro to make sure int3 is
- * always inlined.
- *
- *-----------------------------------------------------------------------------
- */
-
-#ifdef _MSC_VER
-#define DEBUGBREAK() __debugbreak()
-#else
-#define DEBUGBREAK() __asm__ (" int $3 ")
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_asm_x86.h
- *
- * Basic IA32 asm macros
- */
-
-#ifndef _VM_BASIC_ASM_X86_H_
-#define _VM_BASIC_ASM_X86_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-#ifdef VM_X86_64
-/*
- * The gcc inline asm uses the "A" constraint which differs in 32 & 64
- * bit mode. 32 bit means eax and edx, 64 means rax or rdx.
- */
-#error "x86-64 not supported"
-#endif
-
-
-
-
-/*
- * from linux: usr/include/asm/io.h
- */
-#ifdef __GNUC__
-#ifndef __SLOW_DOWN_IO
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
-#else
-#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
-#endif
-#endif
-#elif _MSC_VER
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO __asm jmp SHORT $+2 __asm jmp SHORT $+2
-#else
-#define __SLOW_DOWN_IO __asm out 80h,al
-#endif
-#else
-#error
-#endif
-
-#ifdef REALLY_SLOW_IO
-#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
-#else
-#define SLOW_DOWN_IO __SLOW_DOWN_IO
-#endif
-
-/*
- * FXSAVE/FXRSTOR
- * save/restore SIMD/MMX fpu state
- *
- * The pointer passed in must be 16-byte aligned.
- *
- * Intel and AMD processors behave differently w.r.t. fxsave/fxrstor. Intel
- * processors unconditionally save the exception pointer state (instruction
- * ptr., data ptr., and error instruction opcode). FXSAVE_ES1 and FXRSTOR_ES1
- * work correctly for Intel processors.
- *
- * AMD processors only save the exception pointer state if ES=1. This leads to a
- * security hole whereby one process/VM can inspect the state of another process
- * VM. The AMD recommended workaround involves clobbering the exception pointer
- * state unconditionally, and this is implemented in FXRSTOR_AMD_ES0. Note that
- * FXSAVE_ES1 will only save the exception pointer state for AMD processors if
- * ES=1.
- *
- * The workaround (FXRSTOR_AMD_ES0) only costs 1 cycle more than just doing an
- * fxrstor, on both AMD Opteron and Intel Core CPUs.
- */
-#if defined(__GNUC__)
-static INLINE void
-FXSAVE_ES1(uint8 *save)
-{
- __asm__ __volatile__ ("fxsave %0\n" : "=m" (*save) : : "memory");
-}
-
-static INLINE void
-FXRSTOR_ES1(const uint8 *load)
-{
- __asm__ __volatile__ ("fxrstor %0\n" : : "m" (*load) : "memory");
-}
-
-static INLINE void
-FXRSTOR_AMD_ES0(const uint8 *load)
-{
- uint64 dummy = 0;
-
- __asm__ __volatile__
- ("fnstsw %%ax \n" // Grab x87 ES bit
- "bt $7,%%ax \n" // Test ES bit
- "jnc 1f \n" // Jump if ES=0
- "fnclex \n" // ES=1. Clear it so fild doesn't trap
- "1: \n"
- "ffree %%st(7) \n" // Clear tag bit - avoid poss. stack overflow
- "fildl %0 \n" // Dummy Load from "safe address" changes all
- // x87 exception pointers.
- "fxrstor %1 \n"
- :
- : "m" (dummy), "m" (*load)
- : "ax", "memory");
-}
-#endif /* __GNUC__ */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643232 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 32-bit wide
- *
- * Use this function if you are certain that:
- * o Either the quotient will fit in 32 bits,
- * o Or your code is ready to handle a #DE exception indicating overflow.
- * If that is not the case, then use Div643264(). --hpreg
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE void
-Div643232(uint64 dividend, // IN
- uint32 divisor, // IN
- uint32 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- /* Checked against the Intel manual and GCC --hpreg */
- __asm__(
- "divl %4"
- : "=a" (*quotient),
- "=d" (*remainder)
- : "0" ((uint32)dividend),
- "1" ((uint32)(dividend >> 32)),
- "rm" (divisor)
- : "cc"
- );
-}
-
-#elif _MSC_VER
-
-static INLINE void
-Div643232(uint64 dividend, // IN
- uint32 divisor, // IN
- uint32 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- /* Written and tested by mann, checked by dbudko and hpreg */
- __asm {
- mov eax, DWORD PTR [dividend]
- mov edx, DWORD PTR [dividend+4]
- div DWORD PTR [divisor]
- mov edi, DWORD PTR [quotient]
- mov [edi], eax
- mov edi, DWORD PTR [remainder]
- mov [edi], edx
- }
-}
-
-#else
-#error No compiler defined for Div643232
-#endif
-
-
-#if defined(__GNUC__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643264 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 64-bit wide --hpreg
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Div643264(uint64 dividend, // IN
- uint32 divisor, // IN
- uint64 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- uint32 hQuotient;
- uint32 lQuotient;
-
- /* Checked against the Intel manual and GCC --hpreg */
- __asm__(
- "divl %5" "\n\t"
- "movl %%eax, %0" "\n\t"
- "movl %4, %%eax" "\n\t"
- "divl %5"
- : "=&rm" (hQuotient),
- "=a" (lQuotient),
- "=d" (*remainder)
- : "1" ((uint32)(dividend >> 32)),
- "g" ((uint32)dividend),
- "rm" (divisor),
- "2" (0)
- : "cc"
- );
- *quotient = (uint64)hQuotient << 32 | lQuotient;
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Mul64x3264 --
- *
- * Unsigned integer by fixed point multiplication:
- * Unsigned 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Unsigned 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x32 bits to yield a full 96-bit product.
- * Shift right by shift.
- * Return the low-order 64 bits of the result.
- *
- * Result:
- * Product
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
-{
- uint64 result;
- uint32 tmp1, tmp2;
- // ASSERT(shift >= 0 && shift < 64);
-
- /*
- * Written and tested by mann, improved with suggestions by hpreg.
- *
- * The main improvement over the previous version is that the test
- * of shift against 32 is moved out of the asm and into C code.
- * This lets the compiler delete the test and one of the
- * alternative code sequences in the case where shift is a
- * constant. It also lets us use the best code sequence in each
- * alternative, rather than a compromise. The downside is that in
- * the non-constant case, this version takes slightly more code
- * space.
- *
- * Note on the constraints: We don't really want multiplicand to
- * start in %edx:%eax as the =A constraint dictates; in fact, we'd
- * prefer any *other* two registers. But gcc doesn't have
- * constraint syntax for any other register pair, and trying to
- * constrain ((uint32) multiplicand) to one place and (multiplicand
- * >> 32) to another generates *really* bad code -- gcc is just not
- * smart enough, at least in the version we are currently using.
- */
- if (shift < 32) {
- __asm__("mov %%eax, %2 \n\t" // Save lo(multiplicand) in tmp2
- "mov %%edx, %%eax \n\t" // Get hi(multiplicand)
- "mull %4 \n\t" // p2 = hi(multiplicand) * multiplier
- "xchg %%eax, %2 \n\t" // Save lo(p2) in tmp2, get lo(multiplicand)
- "mov %%edx, %1 \n\t" // Save hi(p2) in tmp1
- "mull %4 \n\t" // p1 = lo(multiplicand) * multiplier
- "addl %2, %%edx \n\t" // hi(p1) += lo(p2)
- "adcl $0, %1 \n\t" // hi(p2) += carry from previous step
- "shrdl %%edx, %%eax \n\t" // result = hi(p2):hi(p1):lo(p1) >> shift
- "shrdl %1, %%edx"
- : "=A" (result),
- "=&r" (tmp1), // use in shrdl requires it to be a register
- "=&r" (tmp2) // could be "=&rm" but "m" is slower
- : "0" (multiplicand),
- "rm" (multiplier),
- "c" (shift)
- : "cc"
- );
- } else {
- __asm__("mov %%edx, %2 \n\t" // Save hi(multiplicand) in tmp2
- "mull %4 \n\t" // p1 = lo(multiplicand) * multiplier
- "mov %%edx, %1 \n\t" // Save hi(p1) in tmp1
- "mov %2, %%eax \n\t" // Discard lo(p1), get hi(multiplicand)
- "mull %4 \n\t" // p2 = hi(multiplicand) * multiplier
- "addl %1, %%eax \n\t" // lo(p2) += hi(p1)
- "adcl $0, %%edx \n\t" // hi(p2) += carry from previous step
- "shrdl %%edx, %%eax \n\t" // result = p2 >> (shift & 31)
- "shrl %%cl, %%edx"
- : "=A" (result),
- "=&r" (tmp1), // could be "=&rm" but "m" is slower
- "=&r" (tmp2) // could be "=&rm" but "m" is slower
- : "0" (multiplicand),
- "rm" (multiplier),
- "c" (shift)
- : "cc"
- );
- }
- return result;
-}
-
-#elif _MSC_VER
-#pragma warning(disable: 4035)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
-{
- // ASSERT(shift >= 0 && shift < 64);
-
- /* Written and tested by mann, checked by dbudko and hpreg */
- __asm {
- mov eax, DWORD PTR [multiplicand+4] // Get hi(multiplicand)
- mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier
- mov ecx, eax // Save lo(p2)
- mov ebx, edx // Save hi(p2)
- mov eax, DWORD PTR [multiplicand] // Get lo(multiplicand)
- mul DWORD PTR [multiplier+0] // p1 = lo(multiplicand) * multiplier
- add edx, ecx // hi(p1) += lo(p2)
- adc ebx, 0 // hi(p2) += carry from previous step
- mov ecx, DWORD PTR [shift] // Get shift
- cmp ecx, 32 // shift < 32?
- jl SHORT l2 // Go if so
- mov eax, edx // result = hi(p2):hi(p1) >> (shift & 31)
- mov edx, ebx
- shrd eax, edx, cl
- shr edx, cl
- jmp SHORT l3
- l2:
- shrd eax, edx, cl // result = hi(p2):hi(p1):lo(p1) >> shift
- shrd edx, ebx, cl
- l3:
- }
- // return with result in edx:eax
-}
-
-#pragma warning(default: 4035)
-#else
-#error No compiler defined for Mul64x3264
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Muls64x32s64 --
- *
- * Signed integer by fixed point multiplication:
- * Signed 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Signed 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x32 bits to yield a full 96-bit product.
- * Shift right by the location of the binary point.
- * Return the low-order 64 bits of the result.
- *
- * Result:
- * Product
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- int64 result;
- uint32 tmp1, tmp2;
- // ASSERT(shift >= 0 && shift < 64);
-
- /* Written and tested by mann, checked by dbudko and hpreg */
- /* XXX hpreg suggested some improvements that we haven't converged on yet */
- __asm__("mov %%eax, %2\n\t" // Save lo(multiplicand)
- "mov %%edx, %%eax\n\t" // Get hi(multiplicand)
- "test %%eax, %%eax\n\t" // Check sign of multiplicand
- "jl 0f\n\t" // Go if negative
- "mull %4\n\t" // p2 = hi(multiplicand) * multiplier
- "jmp 1f\n"
- "0:\n\t"
- "mull %4\n\t" // p2 = hi(multiplicand) * multiplier
- "sub %4, %%edx\n" // hi(p2) += -1 * multiplier
- "1:\n\t"
- "xchg %%eax, %2\n\t" // Save lo(p2), get lo(multiplicand)
- "mov %%edx, %1\n\t" // Save hi(p2)
- "mull %4\n\t" // p1 = lo(multiplicand) * multiplier
- "addl %2, %%edx\n\t" // hi(p1) += lo(p2)
- "adcl $0, %1\n\t" // hi(p2) += carry from previous step
- "cmpl $32, %%ecx\n\t" // shift < 32?
- "jl 2f\n\t" // Go if so
- "mov %%edx, %%eax\n\t" // result = hi(p2):hi(p1) >> (shift & 31)
- "mov %1, %%edx\n\t"
- "shrdl %%edx, %%eax\n\t"
- "sarl %%cl, %%edx\n\t"
- "jmp 3f\n"
- "2:\n\t"
- "shrdl %%edx, %%eax\n\t" // result = hi(p2):hi(p1):lo(p1) >> shift
- "shrdl %1, %%edx\n"
- "3:\n\t"
- : "=A" (result), "=&r" (tmp1), "=&r" (tmp2)
- : "0" (multiplicand), "rm" (multiplier), "c" (shift)
- : "cc");
- return result;
-}
-
-#elif _MSC_VER
-#pragma warning(disable: 4035)
-
-static INLINE int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- //ASSERT(shift >= 0 && shift < 64);
-
- /* Written and tested by mann, checked by dbudko and hpreg */
- __asm {
- mov eax, DWORD PTR [multiplicand+4] // Get hi(multiplicand)
- test eax, eax // Check sign of multiplicand
- jl SHORT l0 // Go if negative
- mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier
- jmp SHORT l1
- l0:
- mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier
- sub edx, DWORD PTR [multiplier] // hi(p2) += -1 * multiplier
- l1:
- mov ecx, eax // Save lo(p2)
- mov ebx, edx // Save hi(p2)
- mov eax, DWORD PTR [multiplicand] // Get lo(multiplicand)
- mul DWORD PTR [multiplier] // p1 = lo(multiplicand) * multiplier
- add edx, ecx // hi(p1) += lo(p2)
- adc ebx, 0 // hi(p2) += carry from previous step
- mov ecx, DWORD PTR [shift] // Get shift
- cmp ecx, 32 // shift < 32?
- jl SHORT l2 // Go if so
- mov eax, edx // result = hi(p2):hi(p1) >> (shift & 31)
- mov edx, ebx
- shrd eax, edx, cl
- sar edx, cl
- jmp SHORT l3
- l2:
- shrd eax, edx, cl // result = hi(p2):hi(p1):lo(p1) << shift
- shrd edx, ebx, cl
- l3:
- }
- // return with result in edx:eax
-}
-
-#pragma warning(default: 4035)
-#else
-#error No compiler defined for Muls64x32s64
-#endif
-
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_asm_x86_64.h
- *
- * Basic x86_64 asm macros.
- */
-
-#ifndef _VM_BASIC_ASM_X86_64_H_
-#define _VM_BASIC_ASM_X86_64_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#ifndef VM_X86_64
-#error "This file is x86-64 only!"
-#endif
-
-#ifdef _MSC_VER
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-uint64 _umul128(uint64 multiplier, uint64 multiplicand,
- uint64 *highProduct);
-int64 _mul128(int64 multiplier, int64 multiplicand,
- int64 *highProduct);
-uint64 __shiftright128(uint64 lowPart, uint64 highPart, uint8 shift);
-#ifdef __cplusplus
-}
-#endif
-
-#pragma intrinsic(_umul128, _mul128, __shiftright128)
-
-#endif // _MSC_VER
-
-/*
- * FXSAVE/FXRSTOR
- * save/restore SIMD/MMX fpu state
- *
- * The pointer passed in must be 16-byte aligned.
- *
- * Intel and AMD processors behave differently w.r.t. fxsave/fxrstor. Intel
- * processors unconditionally save the exception pointer state (instruction
- * ptr., data ptr., and error instruction opcode). FXSAVE_ES1 and FXRSTOR_ES1
- * work correctly for Intel processors.
- *
- * AMD processors only save the exception pointer state if ES=1. This leads to a
- * security hole whereby one process/VM can inspect the state of another process
- * VM. The AMD recommended workaround involves clobbering the exception pointer
- * state unconditionally, and this is implemented in FXRSTOR_AMD_ES0. Note that
- * FXSAVE_ES1 will only save the exception pointer state for AMD processors if
- * ES=1.
- *
- * The workaround (FXRSTOR_AMD_ES0) only costs 1 cycle more than just doing an
- * fxrstor, on both AMD Opteron and Intel Core CPUs.
- */
-#if defined(__GNUC__)
-
-static INLINE void
-FXSAVE_ES1(uint8 *save)
-{
- __asm__ __volatile__ ("fxsaveq %0 \n" : "=m" (*save) : : "memory");
-}
-
-static INLINE void
-FXSAVE_COMPAT_ES1(uint8 *save)
-{
- __asm__ __volatile__ ("fxsave %0 \n" : "=m" (*save) : : "memory");
-}
-
-static INLINE void
-FXRSTOR_ES1(const uint8 *load)
-{
- __asm__ __volatile__ ("fxrstorq %0 \n" : : "m" (*load) : "memory");
-}
-
-static INLINE void
-FXRSTOR_COMPAT_ES1(const uint8 *load)
-{
- __asm__ __volatile__ ("fxrstor %0 \n" : : "m" (*load) : "memory");
-}
-
-static INLINE void
-FXRSTOR_AMD_ES0(const uint8 *load)
-{
- uint64 dummy = 0;
-
- __asm__ __volatile__
- ("fnstsw %%ax \n" // Grab x87 ES bit
- "bt $7,%%ax \n" // Test ES bit
- "jnc 1f \n" // Jump if ES=0
- "fnclex \n" // ES=1. Clear it so fild doesn't trap
- "1: \n"
- "ffree %%st(7) \n" // Clear tag bit - avoid poss. stack overflow
- "fildl %0 \n" // Dummy Load from "safe address" changes all
- // x87 exception pointers.
- "fxrstorq %1 \n"
- :
- : "m" (dummy), "m" (*load)
- : "ax", "memory");
-}
-
-#endif /* __GNUC__ */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Mul64x3264 --
- *
- * Unsigned integer by fixed point multiplication:
- * result = multiplicand * multiplier >> shift
- *
- * Unsigned 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Unsigned 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x64 bits to yield a full 128-bit product.
- * Shift result in RDX:RAX right by "shift".
- * Return the low-order 64 bits of the above.
- *
- * Result:
- * Product
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand,
- uint32 multiplier,
- uint32 shift)
-{
- uint64 result, dummy;
- const uint64 multiplier64 = multiplier;
-
- __asm__("mulq %3 \n\t"
- "shrdq %1, %0 \n\t"
- : "=a" (result),
- "=d" (dummy)
- : "0" (multiplier64),
- "rm" (multiplicand),
- "c" (shift)
- : "cc");
- return result;
-}
-
-#elif defined(_MSC_VER)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
-{
- uint64 tmplo, tmphi;
- tmplo = _umul128(multiplicand, multiplier, &tmphi);
- return __shiftright128(tmplo, tmphi, (uint8) shift);
-}
-
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Muls64x32s64 --
- *
- * Signed integer by fixed point multiplication:
- * result = multiplicand * multiplier >> shift
- *
- * Signed 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Signed 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x64 bits to yield a full 128-bit product.
- * Shift result in RDX:RAX right by "shift".
- * Return the low-order 64 bits of the above.
- *
- * Note: using an unsigned shift instruction is correct because
- * shift < 64 and we return only the low 64 bits of the shifted
- * result.
- *
- * Result:
- * Product
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static inline int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- int64 result, dummy;
- const int64 multiplier64 = multiplier;
-
- __asm__("imulq %3 \n\t"
- "shrdq %1, %0 \n\t"
- : "=a" (result),
- "=d" (dummy)
- : "0" (multiplier64),
- "rm" (multiplicand),
- "c" (shift)
- : "cc");
- return result;
-}
-
-#elif defined(_MSC_VER)
-
-static INLINE int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- int64 tmplo, tmphi;
- tmplo = _mul128(multiplicand, multiplier, &tmphi);
- return __shiftright128(tmplo, tmphi, (uint8) shift);
-}
-
-#endif
-
-
-#if defined(__GNUC__)
-
-static INLINE void *
-uint64set(void *dst, uint64 val, uint64 count)
-{
- int dummy0;
- int dummy1;
- __asm__ __volatile__("\t"
- "cld" "\n\t"
- "rep ; stosq" "\n"
- : "=c" (dummy0), "=D" (dummy1)
- : "0" (count), "1" (dst), "a" (val)
- : "memory", "cc");
- return dst;
-}
-
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643232 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 32-bit wide
- *
- * Use this function if you are certain that the quotient will fit in 32 bits,
- * If that is not the case, a #DE exception was generated in 32-bit version,
- * but not in this 64-bit version. So please be careful.
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__) || defined(_MSC_VER)
-
-static INLINE void
-Div643232(uint64 dividend, // IN
- uint32 divisor, // IN
- uint32 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- *quotient = (uint32)(dividend / divisor);
- *remainder = (uint32)(dividend % divisor);
-}
-
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643264 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 64-bit wide
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE void
-Div643264(uint64 dividend, // IN
- uint32 divisor, // IN
- uint64 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- *quotient = dividend / divisor;
- *remainder = dividend % divisor;
-}
-
-#endif
-
-#endif // _VM_BASIC_ASM_X86_64_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_defs.h --
- *
- * Standard macros for VMware source code.
- */
-
-#ifndef _VM_BASIC_DEFS_H_
-#define _VM_BASIC_DEFS_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-#include "vm_basic_types.h" // For INLINE.
-
-/* Checks for FreeBSD, filtering out VMKERNEL. */
-#define __IS_FREEBSD__ (!defined(VMKERNEL) && defined(__FreeBSD__))
-#define __IS_FREEBSD_VER__(ver) (__IS_FREEBSD__ && __FreeBSD_version >= (ver))
-
-#if defined _WIN32 && defined USERLEVEL
- #include <stddef.h> /*
- * We re-define offsetof macro from stddef, make
- * sure that its already defined before we do it
- */
- #include <windows.h> // for Sleep() and LOWORD() etc.
-#endif
-
-
-/*
- * Simple macros
- */
-
-#if (defined __APPLE__ || defined __FreeBSD__) && \
- (!defined KERNEL && !defined _KERNEL && !defined VMKERNEL && !defined __KERNEL__)
-# include <stddef.h>
-#else
-// XXX the _WIN32 one matches that of VC++, to prevent redefinition warning
-// XXX the other one matches that of gcc3.3.3/glibc2.2.4 to prevent redefinition warnings
-#ifndef offsetof
-#ifdef _WIN32
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-#endif
-#endif // __APPLE__
-
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(a) (sizeof (a) / sizeof *(a))
-#endif
-
-#ifndef MIN
-#define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
-#endif
-
-/* The Solaris 9 cross-compiler complains about these not being used */
-#ifndef sun
-static INLINE int
-Min(int a, int b)
-{
- return a < b ? a : b;
-}
-#endif
-
-#ifndef MAX
-#define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
-#endif
-
-#ifndef sun
-static INLINE int
-Max(int a, int b)
-{
- return a > b ? a : b;
-}
-#endif
-
-#define ROUNDUP(x,y) (((x) + (y) - 1) / (y) * (y))
-#define ROUNDDOWN(x,y) ((x) / (y) * (y))
-#define ROUNDUPBITS(x, bits) (((uintptr_t) (x) + MASK(bits)) & ~MASK(bits))
-#define ROUNDDOWNBITS(x, bits) ((uintptr_t) (x) & ~MASK(bits))
-#define CEILING(x, y) (((x) + (y) - 1) / (y))
-#if defined __APPLE__
-#include <machine/param.h>
-#undef MASK
-#endif
-#define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */
-#define DWORD_ALIGN(x) ((((x)+3) >> 2) << 2)
-#define QWORD_ALIGN(x) ((((x)+4) >> 3) << 3)
-
-#define IMPLIES(a,b) (!(a) || (b))
-
-/*
- * Not everybody (e.g., the monitor) has NULL
- */
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *)0)
-#endif
-#endif
-
-
-/*
- * Token concatenation
- *
- * The C preprocessor doesn't prescan arguments when they are
- * concatenated or stringified. So we need extra levels of
- * indirection to convince the preprocessor to expand its
- * arguments.
- */
-
-#define CONC(x, y) x##y
-#define XCONC(x, y) CONC(x, y)
-#define XXCONC(x, y) XCONC(x, y)
-#define MAKESTR(x) #x
-#define XSTR(x) MAKESTR(x)
-
-
-/*
- * Page operations
- *
- * It has been suggested that these definitions belong elsewhere
- * (like x86types.h). However, I deem them common enough
- * (since even regular user-level programs may want to do
- * page-based memory manipulation) to be here.
- * -- edward
- */
-
-#ifndef PAGE_SHIFT // {
-#if defined VM_I386
- #define PAGE_SHIFT 12
-#elif defined __APPLE__
- #define PAGE_SHIFT 12
-#else
- #error
-#endif
-#endif // }
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE (1<<PAGE_SHIFT)
-#endif
-
-#ifndef PAGE_MASK
-#define PAGE_MASK (PAGE_SIZE - 1)
-#endif
-
-#ifndef PAGE_OFFSET
-#define PAGE_OFFSET(_addr) ((uintptr_t)(_addr)&(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGE_BASE
-#define VM_PAGE_BASE(_addr) ((_addr)&~(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGES_SPANNED
-#define VM_PAGES_SPANNED(_addr, _size) \
- ((((_addr) & (PAGE_SIZE - 1)) + (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
-#endif
-
-#ifndef BYTES_2_PAGES
-#define BYTES_2_PAGES(_nbytes) ((_nbytes) >> PAGE_SHIFT)
-#endif
-
-#ifndef PAGES_2_BYTES
-#define PAGES_2_BYTES(_npages) (((uint64)(_npages)) << PAGE_SHIFT)
-#endif
-
-#ifndef MBYTES_2_PAGES
-#define MBYTES_2_PAGES(_nbytes) ((_nbytes) << (20 - PAGE_SHIFT))
-#endif
-
-#ifndef PAGES_2_MBYTES
-#define PAGES_2_MBYTES(_npages) ((_npages) >> (20 - PAGE_SHIFT))
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SHIFT
-#define VM_PAE_LARGE_PAGE_SHIFT 21
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SIZE
-#define VM_PAE_LARGE_PAGE_SIZE (1 << VM_PAE_LARGE_PAGE_SHIFT)
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_MASK
-#define VM_PAE_LARGE_PAGE_MASK (VM_PAE_LARGE_PAGE_SIZE - 1)
-#endif
-
-#ifndef VM_PAE_LARGE_2_SMALL_PAGES
-#define VM_PAE_LARGE_2_SMALL_PAGES (BYTES_2_PAGES(VM_PAE_LARGE_PAGE_SIZE))
-#endif
-
-/*
- * Word operations
- */
-
-#ifndef LOWORD
-#define LOWORD(_dw) ((_dw) & 0xffff)
-#endif
-#ifndef HIWORD
-#define HIWORD(_dw) (((_dw) >> 16) & 0xffff)
-#endif
-
-#ifndef LOBYTE
-#define LOBYTE(_w) ((_w) & 0xff)
-#endif
-#ifndef HIBYTE
-#define HIBYTE(_w) (((_w) >> 8) & 0xff)
-#endif
-
-#define HIDWORD(_qw) ((uint32)((_qw) >> 32))
-#define LODWORD(_qw) ((uint32)(_qw))
-#define QWORD(_hi, _lo) ((((uint64)(_hi)) << 32) | ((uint32)(_lo)))
-
-
-/*
- * Deposit a field _src at _pos bits from the right,
- * with a length of _len, into the integer _target.
- */
-
-#define DEPOSIT_BITS(_src,_pos,_len,_target) { \
- unsigned mask = ((1 << _len) - 1); \
- unsigned shiftedmask = ((1 << _len) - 1) << _pos; \
- _target = (_target & ~shiftedmask) | ((_src & mask) << _pos); \
-}
-
-
-/*
- * Get return address.
- */
-
-#ifdef _MSC_VER
-#ifdef __cplusplus
-extern "C"
-#endif
-void *_ReturnAddress(void);
-#pragma intrinsic(_ReturnAddress)
-#define GetReturnAddress() _ReturnAddress()
-#elif __GNUC__
-#define GetReturnAddress() __builtin_return_address(0)
-#endif
-
-
-#ifdef __GNUC__
-#ifndef sun
-
-/*
- * Get the frame pointer. We use this assembly hack instead of
- * __builtin_frame_address() due to a bug introduced in gcc 4.1.1
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetFrameAddr(void)
-{
- uintptr_t bp;
-#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0))
- bp = (uintptr_t)__builtin_frame_address(0);
-#elif (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 3)
-# if defined(VMM64) || defined(VM_X86_64)
- __asm__ __volatile__("movq %%rbp, %0\n" : "=g" (bp));
-# else
- __asm__ __volatile__("movl %%ebp, %0\n" : "=g" (bp));
-# endif
-#else
- __asm__ __volatile__(
-#ifdef __linux__
- ".print \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
- ".abort"
-#else /* MacOS */
- ".abort \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
-#endif
- : "=g" (bp)
- );
-#endif
- return bp;
-}
-
-
-/*
- * Returns the frame pointer of the calling function.
- * Equivalent to __builtin_frame_address(1).
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetCallerFrameAddr(void)
-{
- return *(uintptr_t*)GetFrameAddr();
-}
-
-#endif // sun
-#endif // __GNUC__
-
-/*
- * Data prefetch was added in gcc 3.1.1
- * http://www.gnu.org/software/gcc/gcc-3.1/changes.html
- */
-#ifdef __GNUC__
-# if ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 1) || \
- (__GNUC__ == 3 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 1))
-# define PREFETCH_R(var) __builtin_prefetch((var), 0 /* read */, \
- 3 /* high temporal locality */)
-# define PREFETCH_W(var) __builtin_prefetch((var), 1 /* write */, \
- 3 /* high temporal locality */)
-# else
-# define PREFETCH_R(var) ((void)(var))
-# define PREFETCH_W(var) ((void)(var))
-# endif
-#endif /* __GNUC__ */
-
-
-#ifdef USERLEVEL // {
-
-/*
- * Note this might be a problem on NT b/c while sched_yield guarantees it
- * moves you to the end of your priority list, Sleep(0) offers no such
- * guarantee. Bummer. --Jeremy.
- */
-
-#if defined(N_PLAT_NLM)
-/* We do not have YIELD() as we do not need it yet... */
-#elif defined(_WIN32)
-# define YIELD() Sleep(0)
-#else
-# include <sched.h> // For sched_yield. Don't ask. --Jeremy.
-# define YIELD() sched_yield()
-#endif
-
-
-/*
- * Standardize some Posix names on Windows.
- */
-
-#ifdef _WIN32 // {
-
-#define snprintf _snprintf
-#define strtok_r strtok_s
-
-#if (_MSC_VER < 1500)
-#define vsnprintf _vsnprintf
-#endif
-
-typedef int uid_t;
-typedef int gid_t;
-
-static INLINE void
-sleep(unsigned int sec)
-{
- Sleep(sec * 1000);
-}
-
-static INLINE void
-usleep(unsigned long usec)
-{
- Sleep(CEILING(usec, 1000));
-}
-
-typedef int pid_t;
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-#define R_OK 4
-
-#endif // }
-
-/*
- * Macro for username comparison.
- */
-
-#ifdef _WIN32 // {
-#define USERCMP(x,y) Str_Strcasecmp(x,y)
-#else
-#define USERCMP(x,y) strcmp(x,y)
-#endif // }
-
-
-#endif // }
-
-#ifndef va_copy
-
-#ifdef _WIN32
-
-/*
- * Windows needs va_copy. This works for both 32 and 64-bit Windows
- * based on inspection of how varags.h from the Visual C CRTL is
- * implemented. (Future versions of the RTL may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__APPLE__) && defined(KERNEL)
-
-/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__GNUC__) && (__GNUC__ < 3)
-
-/*
- * Old versions of gcc recognize __va_copy, but not va_copy.
- */
-
-#define va_copy(dest, src) __va_copy(dest, src)
-
-#endif // _WIN32
-
-#endif // va_copy
-
-/*
- * This one is outside USERLEVEL because it's used by
- * files compiled into the Windows hgfs driver or the display
- * driver.
- */
-
-#ifdef _WIN32
-#define PATH_MAX 256
-#ifndef strcasecmp
-#define strcasecmp(_s1,_s2) _stricmp((_s1),(_s2))
-#endif
-#ifndef strncasecmp
-#define strncasecmp(_s1,_s2,_n) _strnicmp((_s1),(_s2),(_n))
-#endif
-#endif
-
-/*
- * Convenience macro for COMMUNITY_SOURCE
- */
-#undef EXCLUDE_COMMUNITY_SOURCE
-#ifdef COMMUNITY_SOURCE
- #define EXCLUDE_COMMUNITY_SOURCE(x)
-#else
- #define EXCLUDE_COMMUNITY_SOURCE(x) x
-#endif
-
-#undef COMMUNITY_SOURCE_INTEL_SECRET
-#if !defined(COMMUNITY_SOURCE) || defined(INTEL_SOURCE)
-/*
- * It's ok to include INTEL_SECRET source code for non-commsrc,
- * or for drops directed at Intel.
- */
- #define COMMUNITY_SOURCE_INTEL_SECRET
-#endif
-
-/*
- * Convenience macros and definitions. Can often be used instead of #ifdef.
- */
-
-#undef DEBUG_ONLY
-#undef SL_DEBUG_ONLY
-#undef VMX86_SL_DEBUG
-#ifdef VMX86_DEBUG
-#define vmx86_debug 1
-#define DEBUG_ONLY(x) x
-/*
- * Be very, very, very careful with SL_DEBUG. Pls ask ganesh or min before
- * using it.
- */
-#define VMX86_SL_DEBUG
-#define vmx86_sl_debug 1
-#define SL_DEBUG_ONLY(x) x
-#else
-#define vmx86_debug 0
-#define DEBUG_ONLY(x)
-#define vmx86_sl_debug 0
-#define SL_DEBUG_ONLY(x)
-#endif
-
-#ifdef VMX86_STATS
-#define vmx86_stats 1
-#define STATS_ONLY(x) x
-#else
-#define vmx86_stats 0
-#define STATS_ONLY(x)
-#endif
-
-#ifdef VMX86_DEVEL
-#define vmx86_devel 1
-#define DEVEL_ONLY(x) x
-#else
-#define vmx86_devel 0
-#define DEVEL_ONLY(x)
-#endif
-
-#ifdef VMX86_LOG
-#define vmx86_log 1
-#define LOG_ONLY(x) x
-#else
-#define vmx86_log 0
-#define LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_VMM_SERIAL_LOGGING
-#define vmx86_vmm_serial_log 1
-#define VMM_SERIAL_LOG_ONLY(x) x
-#else
-#define vmx86_vmm_serial_log 0
-#define VMM_SERIAL_LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_SERVER
-#define vmx86_server 1
-#define SERVER_ONLY(x) x
-#define HOSTED_ONLY(x)
-#else
-#define vmx86_server 0
-#define SERVER_ONLY(x)
-#define HOSTED_ONLY(x) x
-#endif
-
-#ifdef VMX86_WGS
-#define vmx86_wgs 1
-#define WGS_ONLY(x) x
-#else
-#define vmx86_wgs 0
-#define WGS_ONLY(x)
-#endif
-
-#ifdef VMKERNEL
-#define vmkernel 1
-#define VMKERNEL_ONLY(x) x
-#else
-#define vmkernel 0
-#define VMKERNEL_ONLY(x)
-#endif
-
-#ifdef _WIN32
-#define WIN32_ONLY(x) x
-#define POSIX_ONLY(x)
-#else
-#define WIN32_ONLY(x)
-#define POSIX_ONLY(x) x
-#endif
-
-#ifdef VMM
-#define VMM_ONLY(x) x
-#define USER_ONLY(x)
-#else
-#define VMM_ONLY(x)
-#define USER_ONLY(x) x
-#endif
-
-/* VMVISOR ifdef only allowed in the vmkernel */
-#ifdef VMKERNEL
-#ifdef VMVISOR
-#define vmvisor 1
-#define VMVISOR_ONLY(x) x
-#else
-#define vmvisor 0
-#define VMVISOR_ONLY(x)
-#endif
-#endif
-
-#ifdef _WIN32
-#define VMW_INVALID_HANDLE INVALID_HANDLE_VALUE
-#else
-#define VMW_INVALID_HANDLE (-1)
-#endif
-
-#ifdef _WIN32
-#define fsync(fd) _commit(fd)
-#define fileno(f) _fileno(f)
-#else
-#endif
-
-/*
- * Debug output macros for Windows drivers (the Eng variant is for
- * display/printer drivers only.
- */
-#ifdef _WIN32
-#ifndef USES_OLD_WINDDK
-#if defined(VMX86_DEBUG) || defined(ASSERT_ALWAYS_AVAILABLE)
-#define WinDrvPrint(arg, ...) DbgPrint(arg, __VA_ARGS__)
-#define WinDrvEngPrint(arg, ...) EngDbgPrint(arg, __VA_ARGS__)
-#else
-#define WinDrvPrint(arg, ...)
-#define WinDrvEngPrint(arg, ...)
-#endif
-#endif
-#endif // _WIN32
-
-#endif // ifndef _VM_BASIC_DEFS_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- *
- * vm_basic_types.h --
- *
- * basic data types.
- */
-
-
-#ifndef _VM_BASIC_TYPES_H_
-#define _VM_BASIC_TYPES_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-/* STRICT ANSI means the Xserver build and X defines Bool differently. */
-#if !defined(__STRICT_ANSI__) || defined(__FreeBSD__)
-typedef char Bool;
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define IsBool(x) (((x) & ~1) == 0)
-#define IsBool2(x, y) ((((x) | (y)) & ~1) == 0)
-
-/*
- * Macros __i386__ and __ia64 are intrinsically defined by GCC
- */
-#ifdef __i386__
-#define VM_I386
-#endif
-
-#ifdef _WIN64
-#define __x86_64__
-#endif
-
-#ifdef __x86_64__
-#define VM_X86_64
-#define VM_I386
-#define vm_x86_64 (1)
-#else
-#define vm_x86_64 (0)
-#endif
-
-
-
-#ifdef _WIN32
-/* safe assumption for a while */
-#define VM_I386
-#endif
-
-#ifdef _MSC_VER
-
-#pragma warning (3 :4505) // unreferenced local function
-#pragma warning (disable :4018) // signed/unsigned mismatch
-#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
-#pragma warning (disable :4305) // truncation from 'const int' to 'short'
-#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
-#pragma warning (disable :4267) // truncation of 'size_t'
-#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
-#pragma warning (disable :4142) // benign redefinition of type
-
-#endif
-
-#if defined(__APPLE__) || defined(HAVE_STDINT_H)
-
-/*
- * TODO: This is a C99 standard header. We should be able to test for
- * #if __STDC_VERSION__ >= 199901L, but that breaks the Netware build
- * (which doesn't have stdint.h).
- */
-
-#include <stdint.h>
-
-typedef uint64_t uint64;
-typedef int64_t int64;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint8_t uint8;
-
-/*
- * XXX: int8_t is defined to be 'signed char' on Mac hosts.
- *
- * Unfortunately, GCC 4.0.1 warns when doing pointer assignment or
- * comparison between signed char * and char * (even if char is
- * signed).
- *
- * If we want to use int8_t to define int8, we need to go through and
- * replace uses of char * with signed char * to prevent warnings.
- */
-typedef char int8;
-
-#else /* !HAVE_STDINT_H */
-
-#ifdef _MSC_VER
-
-typedef unsigned __int64 uint64;
-typedef signed __int64 int64;
-
-#elif __GNUC__
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-#if defined(VM_X86_64)
-typedef unsigned long uint64;
-typedef long int64;
-#else
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#elif __FreeBSD__
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#else
-#error - Need compiler define for int64/uint64
-#endif /* _MSC_VER */
-
-typedef unsigned int uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
-typedef int int32;
-typedef short int16;
-typedef char int8;
-
-#endif /* HAVE_STDINT_H */
-
-/*
- * FreeBSD (for the tools build) unconditionally defines these in
- * sys/inttypes.h so don't redefine them if this file has already
- * been included. [greg]
- *
- * This applies to Solaris as well.
- */
-
-/*
- * Before trying to do the includes based on OS defines, see if we can use
- * feature-based defines to get as much functionality as possible
- */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_INTTYPES_H
-#include <sys/inttypes.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
-#endif
-
-#if !defined(USING_AUTOCONF)
-# if defined(__FreeBSD__) || defined(sun)
-# ifdef KLD_MODULE
-# include <sys/types.h>
-# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
-# include <sys/types.h>
-# else
-# include <sys/inttypes.h>
-# endif
-# endif
-# elif defined __APPLE__
-# if KERNEL
-# include <sys/unistd.h>
-# include <sys/types.h> /* mostly for size_t */
-# include <stdint.h>
-# else
-# include <unistd.h>
-# include <inttypes.h>
-# include <stdlib.h>
-# include <stdint.h>
-# endif
-# else
-# if !defined(__intptr_t_defined) && !defined(intptr_t)
-# define __intptr_t_defined
-# define intptr_t intptr_t
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef int64 intptr_t;
-# else
-typedef int32 intptr_t;
-# endif
-# endif
-# endif
-
-# ifndef _STDINT_H
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef uint64 uintptr_t;
-# else
-typedef uint32 uintptr_t;
-# endif
-# endif
-# endif
-# endif
-#endif
-
-
-/*
- * Time
- * XXX These should be cleaned up. -- edward
- */
-
-typedef int64 VmTimeType; /* Time in microseconds */
-typedef int64 VmTimeRealClock; /* Real clock kept in microseconds */
-typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */
-
-/*
- * Printf format specifiers for size_t and 64-bit number.
- * Use them like this:
- * printf("%"FMT64"d\n", big);
- *
- * FMTH is for handles/fds.
- */
-
-#ifdef _MSC_VER
- #define FMT64 "I64"
- #ifdef VM_X86_64
- #define FMTSZ "I64"
- #define FMTPD "I64"
- #define FMTH "I64"
- #else
- #define FMTSZ "I"
- #define FMTPD "I"
- #define FMTH "I"
- #endif
-#elif defined __APPLE__
- /* Mac OS hosts use the same formatters for 32- and 64-bit. */
- #define FMT64 "ll"
- #define FMTSZ "z"
- #define FMTPD "l"
- #define FMTH ""
-#elif __GNUC__
- #define FMTH ""
- #if defined(N_PLAT_NLM) || defined(sun) || \
- (defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) < 5))
- /*
- * Why (__FreeBSD__ + 0)? See bug 141008.
- * Yes, we really need to test both (__FreeBSD__ + 0) and
- * ((__FreeBSD__ + 0) < 5). No, we can't remove "+ 0" from
- * ((__FreeBSD__ + 0) < 5).
- */
- #ifdef VM_X86_64
- #define FMTSZ "l"
- #define FMTPD "l"
- #else
- #define FMTSZ ""
- #define FMTPD ""
- #endif
- #elif defined(__linux__) \
- || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
- || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
- || (defined(_POSIX2_VERSION) && _POSIX2_VERSION >= 200112L)
- /* BSD, Linux */
- #define FMTSZ "z"
-
- #if defined(VM_X86_64)
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #else
- /* Systems with a pre-C99 libc */
- #define FMTSZ "Z"
- #ifdef VM_X86_64
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #endif
- #ifdef VM_X86_64
- #define FMT64 "l"
- #elif defined(sun) || defined(__FreeBSD__)
- #define FMT64 "ll"
- #else
- #define FMT64 "L"
- #endif
-#else
- #error - Need compiler define for FMT64 and FMTSZ
-#endif
-
-/*
- * Suffix for 64-bit constants. Use it like this:
- * CONST64(0x7fffffffffffffff) for signed or
- * CONST64U(0x7fffffffffffffff) for unsigned.
- *
- * 2004.08.30(thutt):
- * The vmcore/asm64/gen* programs are compiled as 32-bit
- * applications, but must handle 64 bit constants. If the
- * 64-bit-constant defining macros are already defined, the
- * definition will not be overwritten.
- */
-
-#if !defined(CONST64) || !defined(CONST64U)
-#ifdef _MSC_VER
-#define CONST64(c) c##I64
-#define CONST64U(c) c##uI64
-#elif defined __APPLE__
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#elif __GNUC__
-#ifdef VM_X86_64
-#define CONST64(c) c##L
-#define CONST64U(c) c##uL
-#else
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#endif
-#else
-#error - Need compiler define for CONST64
-#endif
-#endif
-
-/*
- * Use CONST3264/CONST3264U if you want a constant to be
- * treated as a 32-bit number on 32-bit compiles and
- * a 64-bit number on 64-bit compiles. Useful in the case
- * of shifts, like (CONST3264U(1) << x), where x could be
- * more than 31 on a 64-bit compile.
- */
-
-#ifdef VM_X86_64
- #define CONST3264(a) CONST64(a)
- #define CONST3264U(a) CONST64U(a)
-#else
- #define CONST3264(a) (a)
- #define CONST3264U(a) (a)
-#endif
-
-#define MIN_INT32 ((int32)0x80000000)
-#define MAX_INT32 ((int32)0x7fffffff)
-
-#define MIN_UINT32 ((uint32)0)
-#define MAX_UINT32 ((uint32)0xffffffff)
-
-#define MIN_INT64 (CONST64(0x8000000000000000))
-#define MAX_INT64 (CONST64(0x7fffffffffffffff))
-
-#define MIN_UINT64 (CONST64U(0))
-#define MAX_UINT64 (CONST64U(0xffffffffffffffff))
-
-typedef uint8 *TCA; /* Pointer into TC (usually). */
-
-/*
- * Type big enough to hold an integer between 0..100
- */
-typedef uint8 Percent;
-#define AsPercent(v) ((Percent)(v))
-#define CHOOSE_PERCENT AsPercent(101)
-
-
-typedef uintptr_t VA;
-typedef uintptr_t VPN;
-
-typedef uint64 PA;
-typedef uint32 PPN;
-
-typedef uint64 PhysMemOff;
-typedef uint64 PhysMemSize;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 BA;
-#endif
-typedef uint32 BPN;
-typedef uint32 PageNum;
-typedef unsigned MemHandle;
-typedef int32 World_ID;
-
-#define INVALID_WORLD_ID ((World_ID)-1)
-
-typedef World_ID User_CartelID;
-#define INVALID_CARTEL_ID INVALID_WORLD_ID
-
-typedef User_CartelID User_SessionID;
-#define INVALID_SESSION_ID INVALID_CARTEL_ID
-
-typedef User_CartelID User_CartelGroupID;
-#define INVALID_CARTELGROUP_ID INVALID_CARTEL_ID
-
-typedef uint32 Worldlet_ID;
-#define INVALID_WORLDLET_ID ((Worldlet_ID)-1)
-
-/* world page number */
-typedef uint32 WPN;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 MA;
-typedef uint32 MPN;
-#endif
-
-/*
- * This type should be used for variables that contain sector
- * position/quantity.
- */
-typedef uint64 SectorType;
-
-/*
- * Linear address
- */
-
-typedef uintptr_t LA;
-typedef uintptr_t LPN;
-#define LA_2_LPN(_la) ((_la) >> PAGE_SHIFT)
-#define LPN_2_LA(_lpn) ((_lpn) << PAGE_SHIFT)
-
-#define LAST_LPN ((((LA) 1) << (8 * sizeof(LA) - PAGE_SHIFT)) - 1)
-#define LAST_LPN32 ((((LA32)1) << (8 * sizeof(LA32) - PAGE_SHIFT)) - 1)
-#define LAST_LPN64 ((((LA64)1) << (8 * sizeof(LA64) - PAGE_SHIFT)) - 1)
-
-/* Valid bits in a LPN. */
-#define LPN_MASK LAST_LPN
-#define LPN_MASK32 LAST_LPN32
-#define LPN_MASK64 LAST_LPN64
-
-/*
- * On 64 bit platform, address and page number types default
- * to 64 bit. When we need to represent a 32 bit address, we use
- * types defined below.
- *
- * On 32 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint32 VA32;
-typedef uint32 VPN32;
-typedef uint32 LA32;
-typedef uint32 LPN32;
-typedef uint32 PA32;
-typedef uint32 PPN32;
-typedef uint32 MA32;
-typedef uint32 MPN32;
-
-/*
- * On 64 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint64 VA64;
-typedef uint64 VPN64;
-typedef uint64 LA64;
-typedef uint64 LPN64;
-typedef uint64 PA64;
-typedef uint64 PPN64;
-typedef uint64 MA64;
-typedef uint64 MPN64;
-
-/*
- * VA typedefs for user world apps.
- */
-typedef VA32 UserVA32;
-typedef VA64 UserVA64;
-typedef UserVA64 UserVAConst; /* Userspace ptr to data that we may only read. */
-typedef UserVA32 UserVA32Const; /* Userspace ptr to data that we may only read. */
-typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */
-#ifdef VMKERNEL
-typedef UserVA64 UserVA;
-#else
-typedef void * UserVA;
-#endif
-
-
-/*
- * Maximal possible PPN value (errors too) that PhysMem can handle.
- * Must be at least as large as MAX_PPN which is the maximum PPN
- * for any region other than buserror.
- */
-#define PHYSMEM_MAX_PPN ((PPN)0xffffffff)
-#define MAX_PPN ((PPN)0x1fffffff) /* Maximal observable PPN value. */
-#define INVALID_PPN ((PPN)0xffffffff)
-
-#define INVALID_BPN ((BPN) 0x1fffffff)
-
-#define INVALID_MPN ((MPN)-1)
-#define MEMREF_MPN ((MPN)-2)
-#define RESERVED_MPN ((MPN) 0)
-/* Support 43 bits of address space. */
-#define MAX_MPN ((MPN)0x7fffffff)
-
-#define INVALID_LPN ((LPN)-1)
-#define INVALID_VPN ((VPN)-1)
-#define INVALID_LPN64 ((LPN64)-1)
-#define INVALID_PAGENUM ((PageNum)-1)
-#define INVALID_WPN ((WPN) -1)
-
-
-/*
- * Format modifier for printing VA, LA, and VPN.
- * Use them like this: Log("%#"FMTLA"x\n", laddr)
- */
-
-#if defined(VMM64) || defined(FROBOS64) || vm_x86_64 || defined __APPLE__
-# define FMTLA "l"
-# define FMTVA "l"
-# define FMTVPN "l"
-#else
-# define FMTLA ""
-# define FMTVA ""
-# define FMTVPN ""
-#endif
-
-#ifndef EXTERN
-#define EXTERN extern
-#endif
-#define CONST const
-
-
-#ifndef INLINE
-# ifdef _MSC_VER
-# define INLINE __inline
-# else
-# define INLINE inline
-# endif
-#endif
-
-
-/*
- * Annotation for data that may be exported into a DLL and used by other
- * apps that load that DLL and import the data.
- */
-#if defined(_WIN32) && defined(VMX86_IMPORT_DLLDATA)
-# define VMX86_EXTERN_DATA extern __declspec(dllimport)
-#else // !_WIN32
-# define VMX86_EXTERN_DATA extern
-#endif
-
-#if defined(_WIN32) && !defined(VMX86_NO_THREADS)
-#define THREADSPECIFIC __declspec(thread)
-#else
-#define THREADSPECIFIC
-#endif
-
-/*
- * Due to the wonderful "registry redirection" feature introduced in
- * 64-bit Windows, if you access any key under HKLM\Software in 64-bit
- * code, you need to open/create/delete that key with
- * VMKEY_WOW64_32KEY if you want a consistent view with 32-bit code.
- */
-
-#ifdef _WIN32
-#ifdef _WIN64
-#define VMW_KEY_WOW64_32KEY KEY_WOW64_32KEY
-#else
-#define VMW_KEY_WOW64_32KEY 0x0
-#endif
-#endif
-
-
-/*
- * Consider the following reasons functions are inlined:
- *
- * 1) inlined for performance reasons
- * 2) inlined because it's a single-use function
- *
- * Functions which meet only condition 2 should be marked with this
- * inline macro; It is not critical to be inlined (but there is a
- * code-space & runtime savings by doing so), so when other callers
- * are added the inline-ness should be removed.
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-/*
- * Starting at version 3.3, gcc does not always inline functions marked
- * 'inline' (it depends on their size). To force gcc to do so, one must use the
- * extra __always_inline__ attribute.
- */
-# define INLINE_SINGLE_CALLER INLINE __attribute__((__always_inline__))
-# if defined(VMM) \
- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
-# warning Verify INLINE_SINGLE_CALLER '__always_inline__' attribute (did \
- monitor size change?)
-# endif
-#else
-# define INLINE_SINGLE_CALLER INLINE
-#endif
-
-/*
- * Used when a hard guaranteed of no inlining is needed. Very few
- * instances need this since the absence of INLINE is a good hint
- * that gcc will not do inlining.
- */
-
-#if defined(__GNUC__) && defined(VMM)
-#define ABSOLUTELY_NOINLINE __attribute__((__noinline__))
-#endif
-
-/*
- * Attributes placed on function declarations to tell the compiler
- * that the function never returns.
- */
-
-#ifdef _MSC_VER
-#define NORETURN __declspec(noreturn)
-#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9)
-#define NORETURN __attribute__((__noreturn__))
-#else
-#define NORETURN
-#endif
-
-/*
- * GCC 3.2 inline asm needs the + constraint for input/ouput memory operands.
- * Older GCCs don't know about it --hpreg
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
-# define VM_ASM_PLUS 1
-#else
-# define VM_ASM_PLUS 0
-#endif
-
-/*
- * Branch prediction hints:
- * LIKELY(exp) - Expression exp is likely TRUE.
- * UNLIKELY(exp) - Expression exp is likely FALSE.
- * Usage example:
- * if (LIKELY(excCode == EXC_NONE)) {
- * or
- * if (UNLIKELY(REAL_MODE(vc))) {
- *
- * We know how to predict branches on gcc3 and later (hopefully),
- * all others we don't so we do nothing.
- */
-
-#if (__GNUC__ >= 3)
-/*
- * gcc3 uses __builtin_expect() to inform the compiler of an expected value.
- * We use this to inform the static branch predictor. The '!!' in LIKELY
- * will convert any !=0 to a 1.
- */
-#define LIKELY(_exp) __builtin_expect(!!(_exp), 1)
-#define UNLIKELY(_exp) __builtin_expect((_exp), 0)
-#else
-#define LIKELY(_exp) (_exp)
-#define UNLIKELY(_exp) (_exp)
-#endif
-
-/*
- * GCC's argument checking for printf-like functions
- * This is conditional until we have replaced all `"%x", void *'
- * with `"0x%08x", (uint32) void *'. Note that %p prints different things
- * on different platforms. Argument checking is enabled for the
- * vmkernel, which has already been cleansed.
- *
- * fmtPos is the position of the format string argument, beginning at 1
- * varPos is the position of the variable argument, beginning at 1
- */
-
-#if defined(__GNUC__)
-# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
-#else
-# define PRINTF_DECL(fmtPos, varPos)
-#endif
-
-#if defined(__GNUC__)
-# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
-#else
-# define SCANF_DECL(fmtPos, varPos)
-#endif
-
-/*
- * UNUSED_PARAM should surround the parameter name and type declaration,
- * e.g. "int MyFunction(int var1, UNUSED_PARAM(int var2))"
- *
- */
-
-#ifndef UNUSED_PARAM
-# if defined(__GNUC__)
-# define UNUSED_PARAM(_parm) _parm __attribute__((__unused__))
-# else
-# define UNUSED_PARAM(_parm) _parm
-# endif
-#endif
-
-/*
- * REGPARM defaults to REGPARM3, i.e., a requent that gcc
- * puts the first three arguments in registers. (It is fine
- * if the function has fewer than three args.) Gcc only.
- * Syntactically, put REGPARM where you'd put INLINE or NORETURN.
- */
-
-#if defined(__GNUC__)
-# define REGPARM0 __attribute__((regparm(0)))
-# define REGPARM1 __attribute__((regparm(1)))
-# define REGPARM2 __attribute__((regparm(2)))
-# define REGPARM3 __attribute__((regparm(3)))
-# define REGPARM REGPARM3
-#else
-# define REGPARM0
-# define REGPARM1
-# define REGPARM2
-# define REGPARM3
-# define REGPARM
-#endif
-
-/*
- * ALIGNED specifies minimum alignment in "n" bytes.
- */
-
-#ifdef __GNUC__
-#define ALIGNED(n) __attribute__((__aligned__(n)))
-#else
-#define ALIGNED(n)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_OFFSET_CHECK -- */ /**
- *
- * \brief Check if the actual offsef of a member in a structure
- * is what is expected
- *
- *
- * \param[in] STRUCT Structure the member is a part of.
- * \param[in] MEMBER Member to check the offset of.
- * \param[in] OFFSET Expected offset of MEMBER in STRUCTURE.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to OFFSET to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == (OFFSET + DEBUG_EXTRA))
-#else
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == OFFSET)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_SIZE_CHECK -- */ /**
- *
- * \brief Check if the actual size of a structure is what is expected
- *
- *
- * \param[in] STRUCT Structure whose size is to be checked.
- * \param[in] SIZE Expected size of STRUCT.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to SIZE to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == (SIZE + DEBUG_EXTRA))
-#else
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == SIZE)
-#endif
-
-/*
- * __func__ is a stringified function name that is part of the C99 standard. The block
- * below defines __func__ on older systems where the compiler does not support that
- * macro.
- */
-#if defined(__GNUC__) \
- && ((__GNUC__ == 2 && __GNUC_MINOR < 96) \
- || (__GNUC__ < 2))
-# define __func__ __FUNCTION__
-#endif
-
-/*
- * Once upon a time, this was used to silence compiler warnings that
- * get generated when the compiler thinks that a function returns
- * when it is marked noreturn. Don't do it. Use NOT_REACHED().
- */
-
-#define INFINITE_LOOP() do { } while (1)
-
-/*
- * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_
- * is defined. Use the same logic here so we don't define it twice. [greg]
- */
-#ifdef __FreeBSD__
-# ifdef _BSD_SIZE_T_
-# undef _BSD_SIZE_T_
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# ifdef _BSD_SSIZE_T_
-# undef _BSD_SSIZE_T_
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#else
-# ifndef _SIZE_T
-# define _SIZE_T
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(ssize_t) && \
- !defined(__ssize_t_defined) && !defined(_SSIZE_T_DECLARED)
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#endif
-
-/*
- * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The pid is %"FMTPID".\n", pid);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTPID "d"
-# else
-# define FMTPID "lu"
-# endif
-#else
-# define FMTPID "d"
-#endif
-
-/*
- * Format modifier for printing uid_t. On Solaris 10 and earlier, uid_t
- * is a ulong, but on other platforms it's an unsigned int.
- * Use this like this: printf("The uid is %"FMTUID".\n", uid);
- */
-#if defined(sun) && !defined(SOL11)
-# ifdef VM_X86_64
-# define FMTUID "u"
-# else
-# define FMTUID "lu"
-# endif
-#else
-# define FMTUID "u"
-#endif
-
-/*
- * Format modifier for printing mode_t. On sun the mode_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The mode is %"FMTMODE".\n", mode);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTMODE "o"
-# else
-# define FMTMODE "lo"
-# endif
-#else
-# define FMTMODE "o"
-#endif
-
-/*
- * Format modifier for printing time_t. Most platforms define a time_t to be
- * a long int, but on FreeBSD (as of 5.0, it seems), the time_t is a signed
- * size quantity. Refer to the definition of FMTSZ to see why we need silly
- * preprocessor arithmetic.
- * Use this like this: printf("The mode is %"FMTTIME".\n", time);
- */
-#if defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) >= 5)
-# define FMTTIME FMTSZ"d"
-#else
-# define FMTTIME "ld"
-#endif
-
-/*
- * Define MXSemaHandle here so both vmmon and vmx see this definition.
- */
-
-#ifdef _WIN32
-typedef uintptr_t MXSemaHandle;
-#else
-typedef int MXSemaHandle;
-#endif
-
-/*
- * Define type for poll device handles.
- */
-
-#ifdef _WIN32
-typedef uintptr_t PollDevHandle;
-#else
-typedef int PollDevHandle;
-#endif
-
-/*
- * Define the utf16_t type.
- */
-
-#if defined(_WIN32) && defined(_NATIVE_WCHAR_T_DEFINED)
-typedef wchar_t utf16_t;
-#else
-typedef uint16 utf16_t;
-#endif
-
-#endif /* _VM_BASIC_TYPES_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware.h --
- *
- * Standard include file for VMware source code.
- */
-
-#ifndef _VMWARE_H_
-#define _VMWARE_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-#include "vm_basic_defs.h"
-#include "vm_assert.h"
-
-/*
- * Global error codes. Currently used internally, but may be exported
- * to customers one day, like VM_E_XXX in vmcontrol_constants.h
- */
-
-typedef enum VMwareStatus {
- VMWARE_STATUS_SUCCESS, /* success */
- VMWARE_STATUS_ERROR, /* generic error */
- VMWARE_STATUS_NOMEM, /* generic memory allocation error */
- VMWARE_STATUS_INSUFFICIENT_RESOURCES, /* internal or system resource limit exceeded */
- VMWARE_STATUS_INVALID_ARGS /* invalid arguments */
-} VMwareStatus;
-
-#define VMWARE_SUCCESS(s) ((s) == VMWARE_STATUS_SUCCESS)
-
-
-#endif // ifndef _VMWARE_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_begin.h --
- *
- * Begin of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(push, 1)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_end.h --
- *
- * End of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(pop)
-#elif __GNUC__
-__attribute__((__packed__))
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __VMWARE_PACK_INIT_H__
-# define __VMWARE_PACK_INIT_H__
-
-
-/*
- * vmware_pack_init.h --
- *
- * Platform-independent code to make the compiler pack (i.e. have them
- * occupy the smallest possible space) structure definitions. The following
- * constructs are known to work --hpreg
- *
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * ;
- *
- * typedef
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * foo;
- */
-
-
-#ifdef _MSC_VER
-/*
- * MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is
- * not balanced within 1 included file. That is annoying because our scheme
- * is based on the pairing being balanced between 2 included files.
- *
- * So we disable this warning, but this is safe because the compiler will also
- * emit warning 4161 when there is more pops than pushes within 1 main
- * file --hpreg
- */
-
-# pragma warning(disable:4103)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
-
-
-#endif /* __VMWARE_PACK_INIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef _X86CPUID_H_
-#define _X86CPUID_H_
-
-/* http://www.sandpile.org/ia32/cpuid.htm */
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMX
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-
-/*
- * The linux kernel's ptrace.h stupidly defines the bare
- * EAX/EBX/ECX/EDX, which wrecks havoc with our preprocessor tricks.
- */
-#undef EAX
-#undef EBX
-#undef ECX
-#undef EDX
-
-typedef struct CPUIDRegs {
- uint32 eax, ebx, ecx, edx;
-} CPUIDRegs;
-
-typedef union CPUIDRegsUnion {
- uint32 array[4];
- CPUIDRegs regs;
-} CPUIDRegsUnion;
-
-/*
- * Results of calling cpuid(eax, ecx) on all host logical CPU.
- */
-#ifdef _MSC_VER
-#pragma warning (disable :4200) // non-std extension: zero-sized array in struct
-#endif
-
-typedef
-#include "vmware_pack_begin.h"
-struct CPUIDReply {
- /*
- * Unique host logical CPU identifier. It does not change across queries, so
- * we use it to correlate the replies of multiple queries.
- */
- uint64 tag; // OUT
-
- CPUIDRegs regs; // OUT
-}
-#include "vmware_pack_end.h"
-CPUIDReply;
-
-typedef
-#include "vmware_pack_begin.h"
-struct CPUIDQuery {
- uint32 eax; // IN
- uint32 ecx; // IN
- uint32 numLogicalCPUs; // IN/OUT
- CPUIDReply logicalCPUs[0]; // OUT
-}
-#include "vmware_pack_end.h"
-CPUIDQuery;
-
-/*
- * CPUID levels the monitor caches and ones that are not cached, but
- * have fields defined below (short name and actual value).
- *
- * The first parameter defines whether the level is masked/tested
- * during power-on/migration. Any level which is marked as FALSE here
- * *must* have all field masks defined as IGNORE in CPUID_FIELD_DATA.
- * A static assert in lib/cpuidcompat/cpuidcompat.c will check this.
- *
- * IMPORTANT: WHEN ADDING A NEW FIELD TO THE CACHED LEVELS, make sure
- * you update vmcore/vmm/cpu/priv.c:Priv_CPUID() and vmcore/vmm64/bt/
- * cpuid_shared.S (and geninfo) to include the new level.
- */
-
-#define CPUID_CACHED_LEVELS \
- CPUIDLEVEL(TRUE, 0, 0) \
- CPUIDLEVEL(TRUE, 1, 1) \
- CPUIDLEVEL(FALSE,400, 0x40000000) \
- CPUIDLEVEL(FALSE,410, 0x40000010) \
- CPUIDLEVEL(FALSE, 80, 0x80000000) \
- CPUIDLEVEL(TRUE, 81, 0x80000001) \
- CPUIDLEVEL(FALSE, 88, 0x80000008) \
- CPUIDLEVEL(TRUE, 8A, 0x8000000A)
-
-#define CPUID_UNCACHED_LEVELS \
- CPUIDLEVEL(FALSE, 4, 4) \
- CPUIDLEVEL(FALSE, 5, 5) \
- CPUIDLEVEL(FALSE, 6, 6) \
- CPUIDLEVEL(FALSE, A, 0xA) \
- CPUIDLEVEL(FALSE, 86, 0x80000006) \
- CPUIDLEVEL(FALSE, 87, 0x80000007) \
-
-#define CPUID_ALL_LEVELS \
- CPUID_CACHED_LEVELS \
- CPUID_UNCACHED_LEVELS
-
-/* Define cached CPUID levels in the form: CPUID_LEVEL_<ShortName> */
-typedef enum {
-#define CPUIDLEVEL(t, s, v) CPUID_LEVEL_##s,
- CPUID_CACHED_LEVELS
-#undef CPUIDLEVEL
- CPUID_NUM_LEVELS
-} CpuidLevels;
-
-/*
- * CPUID result registers
- */
-
-#define CPUID_REGS \
- CPUIDREG(EAX, eax) \
- CPUIDREG(EBX, ebx) \
- CPUIDREG(ECX, ecx) \
- CPUIDREG(EDX, edx)
-
-typedef enum {
-#define CPUIDREG(uc, lc) CPUID_REG_##uc,
- CPUID_REGS
-#undef CPUIDREG
- CPUID_NUM_REGS
-} CpuidRegs;
-
-/*
- * CPU vendors
- */
-
-typedef enum {
- CPUID_VENDOR_UNKNOWN,
- CPUID_VENDOR_COMMON,
- CPUID_VENDOR_INTEL,
- CPUID_VENDOR_AMD,
- CPUID_VENDOR_CYRIX,
- CPUID_VENDOR_VIA,
- CPUID_NUM_VENDORS
-} CpuidVendors;
-
-#define CPUID_INTEL_VENDOR_STRING "GenuntelineI"
-#define CPUID_AMD_VENDOR_STRING "AuthcAMDenti"
-#define CPUID_CYRIX_VENDOR_STRING "CyriteadxIns"
-#define CPUID_VIA_VENDOR_STRING "CentaulsaurH"
-#define CPUID_HYPERV_HYPERVISOR_VENDOR_STRING "Microsoft Hv"
-#define CPUID_INTEL_VENDOR_STRING_FIXED "GenuineIntel"
-#define CPUID_AMD_VENDOR_STRING_FIXED "AuthenticAMD"
-#define CPUID_CYRIX_VENDOR_STRING_FIXED "CyrixInstead"
-#define CPUID_VIA_VENDOR_STRING_FIXED "CentaurHauls"
-
-/*
- * FIELDDEF can be defined to process the CPUID information provided
- * in the following CPUID_FIELD_DATA macro. The first parameter is
- * the CPUID level of the feature (must be defined in CPUID_*_LEVELS.
- * The second parameter is the register the field is contained in
- * (defined in CPUID_REGS). The third field is the vendor this
- * feature applies to. "COMMON" means all vendors apply. UNKNOWN may
- * not be used here. The fourth and fifth parameters are the bit
- * position of the field and the width, respectively. The sixth is
- * the text name of the field.
- *
- * The seventh and eighth parameters specify the default CPUID
- * behavior for power-on, guest view, and migration tests (cpt/rsm &
- * vmotion). The eighth parameter is ignored for types other than
- * MASK & TEST, and must be zero in this case.
- *
- * When adding a new field, be sure to consider its purpose. The
- * following list of types is provided in order of likely use.
- *
- * NOTE: this form of representation is separate from the masking
- * system specified via the config file. That is because this
- * representation must take into account multi-bit fields.
- *
- * HOST - Passthrough host value and cannot change during migration.
- * MASK, 0 - Hide from the guest, because we don't support it or we
- * don't want the guest to know that it exists.
- * IGNORE - Ignore this field for all tests
- *
- * (Think twice before using the below mask types/combinations)
- *
- * MASK, x - Force the guest to always see x, and don't compare for
- * migration -- only APIC as of today; it is controlled by
- * software and we know how to toggle it
- * TEST, x - Require host CPUID field to be x for power-on
- * RSVD - Hidden from the guest, but compared during migration
- *
- *
- * Table to explain mask type meanings:
- *
- * IGNR MASK TEST HOST RSVD
- * --------------------------------------------------------
- * Req'd val for power-on - - x - -
- * Value guest sees * x * * 0
- * Checked on migration? N N Y Y Y
- *
- * * - initial host's power-on CPUID value
- *
- * FIELDDEFA takes a ninth parameter, the name used when creating
- * accessor functions in lib/public/cpuidInfoFuncs.h.
- *
- * FLAGDEF/FLAGDEFA is defined identically to fields, but their
- * accessors are more appropriate for 1-bit flags.
- */
-
-typedef enum {
- CPUID_FIELD_MASK_IGNORE,
- CPUID_FIELD_MASK_MASK,
- CPUID_FIELD_MASK_TEST,
- CPUID_FIELD_MASK_HOST,
- CPUID_FIELD_MASK_RSVD,
- CPUID_NUM_FIELD_MASKS
-} CpuidFieldMasks;
-
-
-typedef enum {
- CPUID_FIELD_SUPPORTED_NO,
- CPUID_FIELD_SUPPORTED_YES,
- CPUID_FIELD_SUPPORTED_ANY,
- CPUID_FIELD_SUPPORTED_NA,
- CPUID_NUM_FIELD_SUPPORTEDS
-} CpuidFieldSupported;
-
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_0 \
-FIELDDEF( 0, EAX, COMMON, 0, 32, NUMLEVELS, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 0, EBX, COMMON, 0, 32, VENDOR1, YES, HOST, 0, TRUE) \
-FIELDDEF( 0, ECX, COMMON, 0, 32, VENDOR3, YES, HOST, 0, TRUE) \
-FIELDDEF( 0, EDX, COMMON, 0, 32, VENDOR2, YES, HOST, 0, TRUE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_1 \
-FIELDDEFA( 1, EAX, COMMON, 0, 4, STEPPING, ANY, IGNORE, 0, FALSE, STEPPING) \
-FIELDDEFA( 1, EAX, COMMON, 4, 4, MODEL, ANY, IGNORE, 0, FALSE, MODEL) \
-FIELDDEFA( 1, EAX, COMMON, 8, 4, FAMILY, YES, HOST, 0, FALSE, FAMILY) \
-FIELDDEF( 1, EAX, COMMON, 12, 2, TYPE, ANY, IGNORE, 0, FALSE) \
-FIELDDEFA( 1, EAX, COMMON, 16, 4, EXTMODEL, ANY, IGNORE, 0, FALSE, EXT_MODEL) \
-FIELDDEFA( 1, EAX, COMMON, 20, 8, EXTFAMILY, YES, HOST, 0, FALSE, EXT_FAMILY) \
-FIELDDEF( 1, EBX, COMMON, 0, 8, BRAND_ID, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 1, EBX, COMMON, 8, 8, CLFL_SIZE, ANY, IGNORE, 0, FALSE) \
-FIELDDEFA( 1, EBX, COMMON, 16, 8, LCPU_COUNT, ANY, IGNORE, 0, FALSE, LCPU_COUNT) \
-FIELDDEFA( 1, EBX, COMMON, 24, 8, APICID, ANY, IGNORE, 0, FALSE, APICID) \
-FLAGDEFA( 1, ECX, COMMON, 0, 1, SSE3, YES, HOST, 0, TRUE, SSE3) \
-FLAGDEF( 1, ECX, INTEL, 2, 1, NDA2, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, COMMON, 3, 1, MWAIT, NO, MASK, 0, FALSE, MWAIT) \
-FLAGDEFA( 1, ECX, INTEL, 4, 1, DSCPL, NO, MASK, 0, FALSE, DSCPL) \
-FLAGDEFA( 1, ECX, INTEL, 5, 1, VMX, NO, MASK, 0, FALSE, VMX) \
-FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 7, 1, EST, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 8, 1, TM2, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, COMMON, 9, 1, SSSE3, YES, HOST, 0, TRUE, SSSE3) \
-FLAGDEF( 1, ECX, INTEL, 10, 1, HTCACHE, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, COMMON, 13, 1, CMPX16, YES, HOST, 0, TRUE, CMPX16) \
-FLAGDEF( 1, ECX, INTEL, 14, 1, xPPR, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 15, 1, PERF_MSR, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 18, 1, DCA, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, INTEL, 19, 1, SSE41, YES, HOST, 0, TRUE, SSE41) \
-FLAGDEFA( 1, ECX, INTEL, 20, 1, SSE42, YES, HOST, 0, TRUE, SSE42) \
-FLAGDEF( 1, ECX, INTEL, 21, 1, X2APIC, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 22, 1, MOVBE, NO, RSVD, 0, TRUE) \
-FLAGDEFA( 1, ECX, COMMON, 23, 1, POPCNT, YES, HOST, 0, TRUE, POPCNT) \
-FLAGDEF( 1, ECX, INTEL, 24, 1, ULE, NO, RSVD, 0, TRUE) \
-FLAGDEF( 1, ECX, INTEL, 26, 1, XSAVE, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 27, 1, OSXSAVE, NO, RSVD, 0, TRUE) \
-FLAGDEFA( 1, ECX, COMMON, 31, 1, HYPERVISOR, ANY, IGNORE, 0, FALSE, HYPERVISOR)\
-FLAGDEFA( 1, EDX, COMMON, 0, 1, FPU, YES, HOST, 0, TRUE, FPU) \
-FLAGDEFA( 1, EDX, COMMON, 1, 1, VME, YES, HOST, 0, FALSE, VME) \
-FLAGDEF( 1, EDX, COMMON, 2, 1, DBGE, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, COMMON, 3, 1, PGSZE, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 4, 1, TSC, YES, HOST, 0, TRUE, TSC) \
-FLAGDEF( 1, EDX, COMMON, 5, 1, MSR, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 6, 1, PAE, YES, HOST, 0, FALSE, PAE) \
-FLAGDEF( 1, EDX, COMMON, 7, 1, MCK, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, COMMON, 8, 1, CPMX, YES, HOST, 0, TRUE) \
-FLAGDEFA( 1, EDX, COMMON, 9, 1, APIC, ANY, MASK, 1, FALSE, APIC) \
-FLAGDEFA( 1, EDX, COMMON, 11, 1, SEP, YES, HOST, 0, TRUE, SEP) \
-FLAGDEFA( 1, EDX, COMMON, 12, 1, MTRR, YES, HOST, 0, FALSE, MTRR) \
-FLAGDEFA( 1, EDX, COMMON, 13, 1, PGE, YES, HOST, 0, FALSE, PGE) \
-FLAGDEFA( 1, EDX, COMMON, 14, 1, MCA, YES, HOST, 0, FALSE, MCA) \
-FLAGDEFA( 1, EDX, COMMON, 15, 1, CMOV, YES, HOST, 0, TRUE, CMOV) \
-FLAGDEFA( 1, EDX, COMMON, 16, 1, PAT, YES, HOST, 0, FALSE, PAT) \
-FLAGDEF( 1, EDX, COMMON, 17, 1, 36PG, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 18, 1, PSN, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 19, 1, CLFL, YES, HOST, 0, TRUE, CLFL) \
-FLAGDEF( 1, EDX, INTEL, 21, 1, DTES, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 22, 1, ACPI, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 23, 1, MMX, YES, HOST, 0, TRUE, MMX) \
-FLAGDEFA( 1, EDX, COMMON, 24, 1, FXSAVE, YES, HOST, 0, TRUE, FXSAVE) \
-FLAGDEFA( 1, EDX, COMMON, 25, 1, SSE, YES, HOST, 0, TRUE, SSE) \
-FLAGDEFA( 1, EDX, COMMON, 26, 1, SSE2, YES, HOST, 0, TRUE, SSE2) \
-FLAGDEF( 1, EDX, INTEL, 27, 1, SS, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 28, 1, HT, NO, MASK, 0, FALSE, HT) \
-FLAGDEF( 1, EDX, INTEL, 29, 1, TM, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 30, 1, IA64, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 31, 1, PBE, NO, MASK, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_4 \
-FIELDDEF( 4, EAX, INTEL, 0, 5, CACHE_TYPE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EAX, INTEL, 5, 3, CACHE_LEVEL, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EAX, INTEL, 14, 12, CACHE_NUMHT_SHARING, NA, IGNORE, 0, FALSE) \
-FIELDDEFA( 4, EAX, INTEL, 26, 6, CORE_COUNT, NA, IGNORE, 0, FALSE, INTEL_CORE_COUNT) \
-FIELDDEF( 4, EBX, INTEL, 0, 12, CACHE_LINE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EBX, INTEL, 12, 10, CACHE_PART, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EBX, INTEL, 22, 10, CACHE_WAYS, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_5 \
-FIELDDEF( 5, EAX, COMMON, 0, 16, MWAIT_MIN_SIZE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EBX, COMMON, 0, 16, MWAIT_MAX_SIZE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 5, ECX, COMMON, 0, 1, MWAIT_EXTENSIONS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 5, ECX, COMMON, 1, 1, MWAIT_INTR_BREAK, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 0, 4, MWAIT_C0_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 4, 4, MWAIT_C1_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 8, 4, MWAIT_C2_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 12, 4, MWAIT_C3_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 16, 4, MWAIT_C4_SUBSTATE, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_6 \
-FLAGDEF( 6, EAX, INTEL, 0, 1, THERMAL_SENSOR, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 6, EAX, INTEL, 1, 1, TURBO_MODE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 6, EBX, INTEL, 0, 4, NUM_INTR_THRESHOLDS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 6, ECX, INTEL, 0, 1, HW_COORD_FEEDBACK, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_A \
-FIELDDEFA( A, EAX, INTEL, 0, 8, PMC_VERSION, NA, IGNORE, 0, FALSE, PMC_VERSION) \
-FIELDDEFA( A, EAX, INTEL, 8, 8, NUM_PMCS, NA, IGNORE, 0, FALSE, NUM_PMCS) \
-FIELDDEF( A, EAX, INTEL, 16, 8, PMC_BIT_WIDTH, NA, IGNORE, 0, FALSE) \
-FIELDDEFA( A, EAX, INTEL, 24, 8, PMC_EBX_LENGTH, NA, IGNORE, 0, FALSE, PMC_EBX_LENGTH) \
-FLAGDEF( A, EBX, INTEL, 0, 1, PMC_CORE_CYCLE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 1, 1, PMC_INSTR_RETIRED, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 2, 1, PMC_REF_CYCLES, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 3, 1, PMC_LAST_LVL_CREF, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 4, 1, PMC_LAST_LVL_CMISS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 5, 1, PMC_BR_INST_RETIRED, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 6, 1, PMC_BR_MISS_RETIRED, NA, IGNORE, 0, FALSE) \
-FIELDDEF( A, EDX, INTEL, 0, 5, PMC_FIXED_NUM, NA, IGNORE, 0, FALSE) \
-FIELDDEF( A, EDX, INTEL, 5, 8, PMC_FIXED_SIZE, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_80 \
-FIELDDEF( 80, EAX, COMMON, 0, 32, NUM_EXT_LEVELS, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 80, EBX, AMD, 0, 32, AMD_VENDOR1, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 80, ECX, AMD, 0, 32, AMD_VENDOR3, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 80, EDX, AMD, 0, 32, AMD_VENDOR2, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_81 \
-FIELDDEF( 81, EAX, INTEL, 0, 32, UNKNOWN81EAX, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 0, 4, STEPPING, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 4, 4, MODEL, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 8, 4, FAMILY, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 12, 2, TYPE, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 16, 4, EXTMODEL, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 20, 8, EXTFAMILY, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EBX, INTEL, 0, 32, UNKNOWN81EBX, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EBX, AMD, 0, 16, BRAND_ID, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EBX, AMD, 16, 16, UNDEF, ANY, IGNORE, 0, FALSE) \
-FLAGDEFA( 81, ECX, COMMON, 0, 1, LAHF, YES, HOST, 0, TRUE, LAHF64) \
-FLAGDEFA( 81, ECX, AMD, 1, 1, CMPLEGACY, NO, MASK, 0, FALSE, CMPLEGACY) \
-FLAGDEFA( 81, ECX, AMD, 2, 1, SVM, NO, MASK, 0, FALSE, SVM) \
-FLAGDEFA( 81, ECX, AMD, 3, 1, EXTAPICSPC, YES, HOST, 0, FALSE, EXTAPICSPC) \
-FLAGDEFA( 81, ECX, AMD, 4, 1, CR8AVAIL, NO, MASK, 0, FALSE, CR8AVAIL) \
-FLAGDEFA( 81, ECX, AMD, 5, 1, ABM, YES, HOST, 0, TRUE, ABM) \
-FLAGDEFA( 81, ECX, AMD, 6, 1, SSE4A, YES, HOST, 0, TRUE, SSE4A) \
-FLAGDEF( 81, ECX, AMD, 7, 1, MISALIGNED_SSE, YES, HOST, 0, TRUE) \
-FLAGDEFA( 81, ECX, AMD, 8, 1, 3DNPREFETCH, YES, HOST, 0, TRUE, 3DNPREFETCH) \
-FLAGDEF( 81, ECX, AMD, 9, 1, OSVW, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, ECX, AMD, 10, 1, IBS, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, ECX, AMD, 11, 1, SSE5, NO, RSVD, 0, TRUE) \
-FLAGDEF( 81, ECX, AMD, 12, 1, SKINIT, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, ECX, AMD, 13, 1, WATCHDOG, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 0, 1, FPU, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 1, 1, VME, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 2, 1, DBGE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 3, 1, PGSZE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 4, 1, TSC, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 5, 1, MSR, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 6, 1, PAE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 7, 1, MCK, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 8, 1, CPMX, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 9, 1, APIC, ANY, MASK, 1, FALSE) \
-FLAGDEFA( 81, EDX, COMMON, 11, 1, SYSC, ANY, IGNORE, 0, TRUE, SYSC) \
-FLAGDEF( 81, EDX, AMD, 12, 1, MTRR, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 13, 1, PGE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 14, 1, MCA, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 15, 1, CMOV, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 16, 1, PAT, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 17, 1, 36PG, YES, HOST, 0, FALSE) \
-FLAGDEFA( 81, EDX, COMMON, 20, 1, NX, YES, HOST, 0, FALSE, NX) \
-FLAGDEFA( 81, EDX, AMD, 22, 1, MMXEXT, YES, HOST, 0, TRUE, MMXEXT) \
-FLAGDEF( 81, EDX, AMD, 23, 1, MMX, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 24, 1, FXSAVE, YES, HOST, 0, TRUE) \
-FLAGDEFA( 81, EDX, AMD, 25, 1, FFXSR, YES, HOST, 0, FALSE, FFXSR) \
-FLAGDEF( 81, EDX, AMD, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
-FLAGDEFA( 81, EDX, COMMON, 27, 1, RDTSCP, YES, HOST, 0, TRUE, RDTSCP) \
-FLAGDEFA( 81, EDX, COMMON, 29, 1, LM, YES, TEST, 1, FALSE, LM) \
-FLAGDEFA( 81, EDX, AMD, 30, 1, 3DNOWPLUS, YES, HOST, 0, TRUE, 3DNOWPLUS) \
-FLAGDEFA( 81, EDX, AMD, 31, 1, 3DNOW, YES, HOST, 0, TRUE, 3DNOW)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_8x \
-FIELDDEF( 86, ECX, AMD, 0, 8, L2CACHE_LINE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, ECX, AMD, 8, 4, L2CACHE_LINE_PER_TAG, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, ECX, AMD, 12, 4, L2CACHE_WAYS, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, ECX, AMD, 16, 16, L2CACHE_SIZE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 0, 8, L3CACHE_LINE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 8, 4, L3CACHE_LINE_PER_TAG,NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 12, 4, L3CACHE_WAYS, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 18, 14, L3CACHE_SIZE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 0, 1, TS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 1, 1, FID, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 2, 1, VID, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 3, 1, TTP, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 4, 1, TM, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 5, 1, STC, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 6, 1, 100MHZSTEPS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 7, 1, HWPSTATE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, COMMON, 8, 1, TSC_INVARIANT, NA, IGNORE, 0, FALSE) \
-FIELDDEFA(88, EAX, COMMON, 0, 8, PHYSBITS, NA, IGNORE, 0, FALSE, PHYS_BITS) \
-FIELDDEFA(88, EAX, COMMON, 8, 8, VIRTBITS, NA, IGNORE, 0, FALSE, VIRT_BITS) \
-FIELDDEFA(88, ECX, AMD, 0, 8, CORE_COUNT, NA, IGNORE, 0, FALSE, AMD_CORE_COUNT) \
-FIELDDEFA(88, ECX, AMD, 12, 4, APICID_COREID_SIZE, NA, IGNORE, 0, FALSE, AMD_APICID_COREID_SIZE) \
-FIELDDEFA(8A, EAX, AMD, 0, 8, SVM_REVISION, NO, MASK, 0, FALSE, SVM_REVISION) \
-FLAGDEF( 8A, EAX, AMD, 8, 1, SVM_HYPERVISOR, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, EAX, AMD, 9, 23, SVMEAX_RSVD, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, EBX, AMD, 0, 32, SVM_N_ASIDS, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, ECX, AMD, 0, 32, SVMECX_RSVD, NO, MASK, 0, FALSE) \
-FLAGDEFA( 8A, EDX, AMD, 0, 1, SVM_NP, NO, MASK, 0, FALSE, NPT) \
-FLAGDEF( 8A, EDX, AMD, 1, 1, SVM_LBR, NO, MASK, 0, FALSE) \
-FLAGDEF( 8A, EDX, AMD, 2, 1, SVM_LOCK, NO, MASK, 0, FALSE) \
-FLAGDEF( 8A, EDX, AMD, 3, 1, SVM_NRIP, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, EDX, AMD, 4, 28, SVMEDX_RSVD, NO, MASK, 0, FALSE)
-
-#define CPUID_FIELD_DATA \
- CPUID_FIELD_DATA_LEVEL_0 \
- CPUID_FIELD_DATA_LEVEL_1 \
- CPUID_FIELD_DATA_LEVEL_4 \
- CPUID_FIELD_DATA_LEVEL_5 \
- CPUID_FIELD_DATA_LEVEL_6 \
- CPUID_FIELD_DATA_LEVEL_A \
- CPUID_FIELD_DATA_LEVEL_80 \
- CPUID_FIELD_DATA_LEVEL_81 \
- CPUID_FIELD_DATA_LEVEL_8x
-
-/*
- * Define all field and flag values as an enum. The result is a full
- * set of values taken from the table above in the form:
- *
- * CPUID_FEATURE_<vendor>_ID<level><reg>_<name> == mask for feature
- * CPUID_<vendor>_ID<level><reg>_<name>_MASK == mask for field
- * CPUID_<vendor>_ID<level><reg>_<name>_SHIFT == offset of field
- *
- * e.g. - CPUID_FEATURE_COMMON_ID1EDX_FPU = 0x1
- * - CPUID_COMMON_ID88EAX_VIRTBITS_MASK = 0xff00
- * - CPUID_COMMON_ID88EAX_VIRTBITS_SHIFT = 8
- *
- * Note: The FEATURE/MASK definitions must use some gymnastics to get
- * around a warning when shifting left by 32.
- */
-#define VMW_BIT_MASK(shift) (((1 << (shift - 1)) << 1) - 1)
-
-#define FIELDDEF(lvl, reg, vend, bitpos, size, name, s, m, v, c3) \
- CPUID_##vend##_ID##lvl##reg##_##name##_SHIFT = bitpos, \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK = \
- VMW_BIT_MASK(size) << bitpos, \
- CPUID_FEATURE_##vend##_ID##lvl##reg##_##name = \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK,
-
-/* Before simplifying this take a look at bug 293638... */
-#define FIELDDEFA(lvl, reg, vend, bitpos, size, name, s, m, v, c3, f) \
- CPUID_##vend##_ID##lvl##reg##_##name##_SHIFT = bitpos, \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK = \
- VMW_BIT_MASK(size) << bitpos, \
- CPUID_FEATURE_##vend##_ID##lvl##reg##_##name = \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK,
-
-#define FLAGDEFA FIELDDEFA
-#define FLAGDEF FIELDDEF
-
-enum {
- /* Define data for every CPUID field we have */
- CPUID_FIELD_DATA
-};
-#undef VMW_BIT_MASK
-#undef FIELDDEF
-#undef FLAGDEF
-#undef FIELDDEFA
-#undef FLAGDEFA
-
-/*
- * Legal CPUID config file mask characters. For a description of the
- * cpuid masking system, please see:
- *
- * http://vmweb.vmware.com/~mts/cgi-bin/view.cgi/Apps/CpuMigrationChecks
- */
-
-#define CPUID_MASK_HIDE_CHR '0'
-#define CPUID_MASK_HIDE_STR "0"
-#define CPUID_MASK_FORCE_CHR '1'
-#define CPUID_MASK_FORCE_STR "1"
-#define CPUID_MASK_PASS_CHR '-'
-#define CPUID_MASK_PASS_STR "-"
-#define CPUID_MASK_TRUE_CHR 'T'
-#define CPUID_MASK_TRUE_STR "T"
-#define CPUID_MASK_FALSE_CHR 'F'
-#define CPUID_MASK_FALSE_STR "F"
-#define CPUID_MASK_IGNORE_CHR 'X'
-#define CPUID_MASK_IGNORE_STR "X"
-#define CPUID_MASK_HOST_CHR 'H'
-#define CPUID_MASK_HOST_STR "H"
-#define CPUID_MASK_RSVD_CHR 'R'
-#define CPUID_MASK_RSVD_STR "R"
-#define CPUID_MASK_INSTALL_CHR 'I'
-#define CPUID_MASK_INSTALL_STR "I"
-
-/*
- * If a level is listed as not masked/tested in CPUID_LEVELS above,
- * use all "don't care" values for its mask.
- */
-
-#define CPT_DFLT_UNDEFINED_MASK "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX"
-
-/*
- * When LM is disabled, we overlay the following masks onto the
- * guest's default masks. Any level that is not defined below should
- * be treated as all "-"s
- */
-
-#define CPT_ID1ECX_LM_DISABLED "----:----:----:----:--0-:----:----:----"
-#define CPT_ID81EDX_LM_DISABLED "--0-:----:----:----:----:----:----:----"
-#define CPT_ID81ECX_LM_DISABLED "----:----:----:----:----:----:----:---0"
-
-#define CPT_GET_LM_DISABLED_MASK(lvl, reg) \
- ((lvl == 1 && reg == CPUID_REG_ECX) ? CPT_ID1ECX_LM_DISABLED : \
- (lvl == 0x80000001 && reg == CPUID_REG_ECX) ? CPT_ID81ECX_LM_DISABLED : \
- (lvl == 0x80000001 && reg == CPUID_REG_EDX) ? CPT_ID81EDX_LM_DISABLED : \
- NULL)
-
-/*
- * Macro to define GET and SET functions for various common CPUID
- * fields. To create function for a new field, simply name it (CPUID_
- * and CPUID_SET_ are automatically prepended), and list the field
- * name that it needs to use.
- */
-
-#define FIELD_FUNC(name, field) \
- static INLINE uint32 CPUID_##name(uint32 reg) \
- { \
- return (reg & field##_MASK) >> field##_SHIFT; \
- } \
- static INLINE void CPUID_SET_##name(uint32 *reg, uint32 val) \
- { \
- *reg = (*reg & ~field##_MASK) | (val << field##_SHIFT); \
- }
-
-FIELD_FUNC(STEPPING, CPUID_COMMON_ID1EAX_STEPPING)
-FIELD_FUNC(MODEL, CPUID_COMMON_ID1EAX_MODEL)
-FIELD_FUNC(FAMILY, CPUID_COMMON_ID1EAX_FAMILY)
-FIELD_FUNC(TYPE, CPUID_COMMON_ID1EAX_TYPE)
-FIELD_FUNC(EXTENDED_MODEL, CPUID_COMMON_ID1EAX_EXTMODEL)
-FIELD_FUNC(EXTENDED_FAMILY, CPUID_COMMON_ID1EAX_EXTFAMILY)
-FIELD_FUNC(LCPU_COUNT, CPUID_COMMON_ID1EBX_LCPU_COUNT)
-FIELD_FUNC(APICID, CPUID_COMMON_ID1EBX_APICID)
-FIELD_FUNC(PA_BITS, CPUID_COMMON_ID88EAX_PHYSBITS)
-FIELD_FUNC(VIRT_BITS, CPUID_COMMON_ID88EAX_VIRTBITS)
-FIELD_FUNC(SVM_REVISION, CPUID_AMD_ID8AEAX_SVM_REVISION)
-FIELD_FUNC(SVM_N_ASIDS, CPUID_AMD_ID8AEBX_SVM_N_ASIDS)
-FIELD_FUNC(INTEL_CORE_COUNT, CPUID_INTEL_ID4EAX_CORE_COUNT)
-FIELD_FUNC(AMD_CORE_COUNT, CPUID_AMD_ID88ECX_CORE_COUNT)
-FIELD_FUNC(AMD_APICID_COREID_SIZE, CPUID_AMD_ID88ECX_APICID_COREID_SIZE)
-FIELD_FUNC(AMD_EXTAPICSPC, CPUID_AMD_ID81ECX_EXTAPICSPC)
-FIELD_FUNC(NUM_PMCS, CPUID_INTEL_IDAEAX_NUM_PMCS)
-FIELD_FUNC(MWAIT_MIN_SIZE, CPUID_COMMON_ID5EAX_MWAIT_MIN_SIZE)
-FIELD_FUNC(MWAIT_MAX_SIZE, CPUID_COMMON_ID5EBX_MWAIT_MAX_SIZE)
-FIELD_FUNC(MWAIT_C0_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C0_SUBSTATE)
-FIELD_FUNC(MWAIT_C1_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C1_SUBSTATE)
-FIELD_FUNC(MWAIT_C2_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C2_SUBSTATE)
-FIELD_FUNC(MWAIT_C3_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C3_SUBSTATE)
-FIELD_FUNC(MWAIT_C4_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C4_SUBSTATE)
-#undef FIELD_FUNC
-
-
-/*
- * Definitions of various fields' values and more complicated
- * macros/functions for reading cpuid fields.
- */
-
-/* Effective Intel CPU Families */
-#define CPUID_FAMILY_486 4
-#define CPUID_FAMILY_P5 5
-#define CPUID_FAMILY_P6 6
-#define CPUID_FAMILY_P4 15
-
-/* Effective AMD CPU Families */
-#define CPUID_FAMILY_5x86 4
-#define CPUID_FAMILY_K5 5
-#define CPUID_FAMILY_K6 5
-#define CPUID_FAMILY_K7 6
-#define CPUID_FAMILY_K8 15
-#define CPUID_FAMILY_K8L 16
-#define CPUID_FAMILY_K8MOBILE 17
-#define CPUID_FAMILY_EXTENDED 15
-
-/* Intel model information */
-#define CPUID_MODEL_PPRO 1
-#define CPUID_MODEL_PII_03 3
-#define CPUID_MODEL_PII_05 5
-#define CPUID_MODEL_CELERON_06 6
-#define CPUID_MODEL_PM_09 9
-#define CPUID_MODEL_PM_0D 13
-#define CPUID_MODEL_PM_0E 14 // Yonah / Sossaman
-#define CPUID_MODEL_CORE_0F 15 // Conroe / Merom
-#define CPUID_MODEL_CORE_17 0x17 // Penryn
-#define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown
-#define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville
-#define CPUID_MODEL_CORE_1D 0x1d // Dunnington
-#define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield
-
-#define CPUID_MODEL_PIII_07 7
-#define CPUID_MODEL_PIII_08 8
-#define CPUID_MODEL_PIII_0A 10
-
-/* AMD model information */
-#define CPUID_MODEL_BARCELONA_02 0x02 // Barcelona (both Opteron & Phenom kind)
-
-/*
- *----------------------------------------------------------------------
- *
- * CPUID_IsVendor{AMD,Intel} --
- *
- * Determines if the vendor string in cpuid id0 is from {AMD,Intel}.
- *
- * Results:
- * True iff vendor string is CPUID_{AMD,INTEL}_VENDOR_STRING
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static INLINE Bool
-CPUID_IsRawVendor(CPUIDRegs *id0, const char* vendor)
-{
- // hard to get strcmp() in some environments, so do it in the raw
- return (id0->ebx == *(const uint32 *) (vendor + 0) &&
- id0->ecx == *(const uint32 *) (vendor + 4) &&
- id0->edx == *(const uint32 *) (vendor + 8));
-}
-
-static INLINE Bool
-CPUID_IsVendorAMD(CPUIDRegs *id0)
-{
- return CPUID_IsRawVendor(id0, CPUID_AMD_VENDOR_STRING);
-}
-
-static INLINE Bool
-CPUID_IsVendorIntel(CPUIDRegs *id0)
-{
- return CPUID_IsRawVendor(id0, CPUID_INTEL_VENDOR_STRING);
-}
-
-
-static INLINE uint32
-CPUID_EFFECTIVE_FAMILY(uint32 v) /* %eax from CPUID with %eax=1. */
-{
- return CPUID_FAMILY(v) +
- (CPUID_FAMILY(v) == CPUID_FAMILY_EXTENDED ? CPUID_EXTENDED_FAMILY(v) : 0);
-}
-
-/* Normally only used when FAMILY==CPUID_FAMILY_EXTENDED, but Intel is
- * now using the extended model field for FAMILY==CPUID_FAMILY_P6 to
- * refer to the newer Core2 CPUs
- */
-static INLINE uint32
-CPUID_EFFECTIVE_MODEL(uint32 v) /* %eax from CPUID with %eax=1. */
-{
- return CPUID_MODEL(v) + (CPUID_EXTENDED_MODEL(v) << 4);
-}
-
-/*
- * Notice that CPUID families for Intel and AMD overlap. The following macros
- * should only be used AFTER the manufacturer has been established (through
- * the use of CPUID standard function 0).
- */
-static INLINE Bool
-CPUID_FAMILY_IS_486(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_486;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_P5(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P5;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_P6(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P6;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_PENTIUM4(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P4;
-}
-
-/*
- * Intel Pentium M processors are Yonah/Sossaman or an older P-M
- */
-static INLINE Bool
-CPUID_UARCH_IS_PENTIUM_M(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /* Assumes the CPU manufacturer is Intel. */
- return CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_09 ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0D ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0E);
-}
-
-/*
- * Intel Core processors are Merom, Conroe, Woodcrest, Clovertown,
- * Penryn, Dunnington, Kentsfield, Yorktown, Harpertown, ........
- */
-static INLINE Bool
-CPUID_UARCH_IS_CORE(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- uint32 model = CPUID_EFFECTIVE_MODEL(v);
- /* Assumes the CPU manufacturer is Intel. */
- return CPUID_FAMILY_IS_P6(v) &&
- model >= CPUID_MODEL_CORE_0F &&
- (model < CPUID_MODEL_NEHALEM_1A ||
- model == CPUID_MODEL_CORE_1D);
-}
-
-/*
- * Intel Nehalem processors are: Nehalem, Gainestown, Lynnfield.
- */
-static INLINE Bool
-CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /* Assumes the CPU manufacturer is Intel. */
- return CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1A ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1E);
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K7(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K7;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8EXT(uint32 _eax)
-{
- /*
- * We check for this pattern often enough that it's
- * worth a separate function, for syntactic sugar.
- */
- return CPUID_FAMILY_IS_K8(_eax) &&
- CPUID_EXTENDED_MODEL(_eax) != 0;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8L(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8L;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8MOBILE(uint32 _eax)
-{
- /* Essentially a K8 (not K8L) part, but with mobile features. */
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8MOBILE;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8STAR(uint32 _eax)
-{
- /*
- * Read function name as "K8*", as in wildcard.
- * Matches K8 or K8L or K8MOBILE
- */
- return CPUID_FAMILY_IS_K8(_eax) || CPUID_FAMILY_IS_K8L(_eax) ||
- CPUID_FAMILY_IS_K8MOBILE(_eax);
-}
-
-/*
- * AMD Barcelona (of either Opteron or Phenom kind).
- */
-static INLINE Bool
-CPUID_MODEL_IS_BARCELONA(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /* Assumes the CPU manufacturer is AMD. */
- return CPUID_FAMILY_IS_K8L(v) &&
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_BARCELONA_02;
-}
-
-
-#define CPUID_TYPE_PRIMARY 0
-#define CPUID_TYPE_OVERDRIVE 1
-#define CPUID_TYPE_SECONDARY 2
-
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_NULL 0
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_DATA 1
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_INST 2
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_UNIF 3
-
-#define CPUID_INTEL_ID4EAX_CACHE_SELF_INIT 0x00000100
-#define CPUID_INTEL_ID4EAX_CACHE_FULLY_ASSOC 0x00000200
-
-
-/*
- * On AMD chips before Opteron and Intel chips before P4 model 3,
- * WRMSR(TSC) clears the upper half of the TSC instead of using %edx.
- */
-static INLINE Bool
-CPUID_FullyWritableTSC(Bool isIntel, // IN
- uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /*
- * Returns FALSE if:
- * - Intel && P6 (pre-core) or
- * - Intel && P4 (model < 3) or
- * - !Intel && pre-K8 Opteron
- * Otherwise, returns TRUE.
- */
- return !((isIntel &&
- ((CPUID_FAMILY_IS_P6(v) &&
- CPUID_EFFECTIVE_MODEL(v) < CPUID_MODEL_PM_0E) ||
- (CPUID_FAMILY_IS_PENTIUM4(v) &&
- CPUID_EFFECTIVE_MODEL(v) < 3))) ||
- (!isIntel &&
- CPUID_FAMILY(v) < CPUID_FAMILY_K8));
-}
-
-
-/*
- * For certain AMD processors, an lfence instruction is necessary at various
- * places to ensure ordering.
- */
-
-static INLINE Bool
-CPUID_VendorRequiresFence(CpuidVendors vendor)
-{
- return vendor == CPUID_VENDOR_AMD;
-}
-
-static INLINE Bool
-CPUID_VersionRequiresFence(uint32 version)
-{
- return CPUID_EFFECTIVE_FAMILY(version) == CPUID_FAMILY_K8 &&
- CPUID_EFFECTIVE_MODEL(version) < 0x40;
-}
-
-static INLINE Bool
-CPUID_ID0RequiresFence(CPUIDRegs *id0)
-{
- if (id0->eax == 0) {
- return FALSE;
- }
- return CPUID_IsVendorAMD(id0);
-}
-
-static INLINE Bool
-CPUID_ID1RequiresFence(CPUIDRegs *id1)
-{
- return CPUID_VersionRequiresFence(id1->eax);
-}
-
-static INLINE Bool
-CPUID_RequiresFence(CpuidVendors vendor, // IN
- uint32 version) // IN: %eax from CPUID with %eax=1.
-{
- return CPUID_VendorRequiresFence(vendor) &&
- CPUID_VersionRequiresFence(version);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * CPUID_CountsCPUIDAsBranch --
- *
- * Returns TRUE iff the cpuid given counts CPUID as a branch
- * (i.e. is a pre-Merom E CPU).
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE Bool
-CPUID_CountsCPUIDAsBranch(uint32 v) /* %eax from CPUID with %eax=1 */
-{
- /*
- * CPUID no longer a branch starting with Merom E. Bug 148411.
- * Penryn (Extended Model: 1) also has this fixed.
- *
- * Merom E is: CPUID.1.eax & 0xfff = 0x6f9
- */
- return !(CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) > CPUID_MODEL_CORE_0F ||
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_CORE_0F &&
- CPUID_STEPPING(v) >= 9)));
-}
-
-/*
- * On Merom and later Intel chips, not present PDPTEs with reserved bits
- * set do not fault with a #GP. See PR# 109120.
- */
-static INLINE Bool
-CPUID_FaultOnNPReservedPDPTE(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- return !(CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) >= CPUID_MODEL_CORE_0F));
-}
-
-
-/*
- * The following low-level functions compute the number of
- * cores per cpu. They should be used cautiously because
- * they do not necessarily work on all types of CPUs.
- * High-level functions that are correct for all CPUs are
- * available elsewhere: see lib/cpuidInfo/cpuidInfo.c.
- */
-
-static INLINE uint32
-CPUID_IntelCoresPerPackage(uint32 v) /* %eax from CPUID with %eax=4 and %ecx=0. */
-{
- // Note: This is not guaranteed to work on older Intel CPUs.
- return 1 + CPUID_INTEL_CORE_COUNT(v);
-}
-
-static INLINE uint32
-CPUID_AMDCoresPerPackage(uint32 v) /* %ecx from CPUID with %eax=0x80000008. */
-{
- // Note: This is not guaranteed to work on older AMD CPUs.
- return 1 + CPUID_AMD_CORE_COUNT(v);
-}
-
-/*
- * Hypervisor CPUID space is 0x400000XX.
- */
-static INLINE Bool
-CPUID_IsHypervisorLevel(uint32 level, uint32 *offset)
-{
- *offset = level & 0xff;
- return (level & 0xffffff00) == 0x40000000;
-}
-
-
-#endif
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmmemctl
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#### VMware vmballoon Makefile to be distributed externally
####
-INCLUDE := -I.
+INCLUDE += -I.
+
+ifdef OVT_SOURCE_DIR
+INCLUDE += -I$(call VMLIB_PATH,backdoor)
+endif
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
obj-m += $(DRIVER).o
CC_KFLAGS += -DCPU=586 $(call check_gcc,-march=i586,-m486)
endif
-INCLUDE := -I$(HEADER_DIR)
+INCLUDE += -I$(HEADER_DIR)
+ifeq ($(USE_SHARED_DIR),1)
+INCLUDE += -I$(call VMLIB_PATH,backdoor)
+endif
+
INCLUDE += $(shell $(CC) $(CC_OPTS) $(INCLUDE) \
- -E $(SRCROOT)/autoconf/geninclude.c \
+ -E $(AUTOCONF_DIR)/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
+ifdef OVT_SOURCE_DIR
+INCLUDE += -I$(call VMLIB_PATH,backdoor)
+endif
+
+
CC_OPTS := -g3 -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS)
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
OBJS += os.o
OBJS += vmballoon.o
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Detect whether we have 'struct poll_wqueues'
- * 2.6.x kernels always had this struct. Stock 2.4.x kernels
- * never had it, but some distros backported epoll patch.
- */
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-#include <linux/poll.h>
-
-void poll_test(void) {
- struct poll_wqueues test;
-
- return poll_initwait(&test);
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-
-#ifdef CONFIG_X86_VOYAGER
-APATH/mach-voyager
-#endif
-#ifdef CONFIG_X86_VISWS
-APATH/mach-visws
-#endif
-#ifdef CONFIG_X86_NUMAQ
-APATH/mach-numaq
-#endif
-#ifdef CONFIG_X86_BIGSMP
-APATH/mach-bigsmp
-#endif
-#ifdef CONFIG_X86_SUMMIT
-APATH/mach-summit
-#endif
-#ifdef CONFIG_X86_GENERICARCH
-APATH/mach-generic
-#endif
-APATH/mach-default
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * set_user_nice appeared in 2.4.21. But some distros
- * backported it to older kernels.
- */
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 21)
-#include <linux/sched.h>
-
-void test(void) {
- set_user_nice(current, -20);
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * backdoorInt.h --
- *
- * Internal function prototypes for the real backdoor work.
- */
-
-void BackdoorHbIn(Backdoor_proto_hb *bp);
-void BackdoorHbOut(Backdoor_proto_hb *bp);
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * backdoor_def.h --
- *
- * This contains backdoor defines that can be included from
- * an assembly language file.
- */
-
-
-
-#ifndef _BACKDOOR_DEF_H_
-#define _BACKDOOR_DEF_H_
-
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMKERNEL
-#include "includeCheck.h"
-
-/*
- * If you want to add a new low-level backdoor call for a guest userland
- * application, please consider using the GuestRpc mechanism instead. --hpreg
- */
-
-#define BDOOR_MAGIC 0x564D5868
-
-/* Low-bandwidth backdoor port. --hpreg */
-
-#define BDOOR_PORT 0x5658
-
-#define BDOOR_CMD_GETMHZ 1
-/*
- * BDOOR_CMD_APMFUNCTION is used by:
- *
- * o The FrobOS code, which instead should either program the virtual chipset
- * (like the new BIOS code does, matthias offered to implement that), or not
- * use any VM-specific code (which requires that we correctly implement
- * "power off on CLI HLT" for SMP VMs, boris offered to implement that)
- *
- * o The old BIOS code, which will soon be jettisoned
- *
- * --hpreg
- */
-#define BDOOR_CMD_APMFUNCTION 2
-#define BDOOR_CMD_GETDISKGEO 3
-#define BDOOR_CMD_GETPTRLOCATION 4
-#define BDOOR_CMD_SETPTRLOCATION 5
-#define BDOOR_CMD_GETSELLENGTH 6
-#define BDOOR_CMD_GETNEXTPIECE 7
-#define BDOOR_CMD_SETSELLENGTH 8
-#define BDOOR_CMD_SETNEXTPIECE 9
-#define BDOOR_CMD_GETVERSION 10
-#define BDOOR_CMD_GETDEVICELISTELEMENT 11
-#define BDOOR_CMD_TOGGLEDEVICE 12
-#define BDOOR_CMD_GETGUIOPTIONS 13
-#define BDOOR_CMD_SETGUIOPTIONS 14
-#define BDOOR_CMD_GETSCREENSIZE 15
-#define BDOOR_CMD_MONITOR_CONTROL 16
-#define BDOOR_CMD_GETHWVERSION 17
-#define BDOOR_CMD_OSNOTFOUND 18
-#define BDOOR_CMD_GETUUID 19
-#define BDOOR_CMD_GETMEMSIZE 20
-#define BDOOR_CMD_HOSTCOPY 21 /* Devel only */
-#define BDOOR_CMD_SERVICE_VM 22 /* prototype only */
-#define BDOOR_CMD_GETTIME 23 /* Deprecated. Use GETTIMEFULL. */
-#define BDOOR_CMD_STOPCATCHUP 24
-#define BDOOR_CMD_PUTCHR 25 /* Devel only */
-#define BDOOR_CMD_ENABLE_MSG 26 /* Devel only */
-#define BDOOR_CMD_GOTO_TCL 27 /* Devel only */
-#define BDOOR_CMD_INITPCIOPROM 28
-#define BDOOR_CMD_INT13 29
-#define BDOOR_CMD_MESSAGE 30
-#define BDOOR_CMD_RSVD0 31
-#define BDOOR_CMD_RSVD1 32
-#define BDOOR_CMD_RSVD2 33
-#define BDOOR_CMD_ISACPIDISABLED 34
-#define BDOOR_CMD_TOE 35 /* Not in use */
-#define BDOOR_CMD_ISMOUSEABSOLUTE 36
-#define BDOOR_CMD_PATCH_SMBIOS_STRUCTS 37
-#define BDOOR_CMD_MAPMEM 38 /* Devel only */
-#define BDOOR_CMD_ABSPOINTER_DATA 39
-#define BDOOR_CMD_ABSPOINTER_STATUS 40
-#define BDOOR_CMD_ABSPOINTER_COMMAND 41
-#define BDOOR_CMD_TIMER_SPONGE 42
-#define BDOOR_CMD_PATCH_ACPI_TABLES 43
-/* Catch-all to allow synchronous tests */
-#define BDOOR_CMD_DEVEL_FAKEHARDWARE 44 /* Debug only - needed in beta */
-#define BDOOR_CMD_GETHZ 45
-#define BDOOR_CMD_GETTIMEFULL 46
-#define BDOOR_CMD_STATELOGGER 47
-#define BDOOR_CMD_CHECKFORCEBIOSSETUP 48
-#define BDOOR_CMD_LAZYTIMEREMULATION 49
-#define BDOOR_CMD_BIOSBBS 50
-#define BDOOR_CMD_VASSERT 51
-#define BDOOR_CMD_ISGOSDARWIN 52
-#define BDOOR_CMD_DEBUGEVENT 53
-#define BDOOR_CMD_OSNOTMACOSXSERVER 54
-#define BDOOR_CMD_GETTIMEFULL_WITH_LAG 55
-#define BDOOR_CMD_ACPI_HOTPLUG_DEVICE 56
-#define BDOOR_CMD_ACPI_HOTPLUG_MEMORY 57
-#define BDOOR_CMD_ACPI_HOTPLUG_CBRET 58
-#define BDOOR_CMD_GET_HOST_VIDEO_MODES 59
-#define BDOOR_CMD_ACPI_HOTPLUG_CPU 60
-#define BDOOR_CMD_MAX 61
-
-/*
- * IMPORTANT NOTE: When modifying the behavior of an existing backdoor command,
- * you must adhere to the semantics expected by the oldest Tools who use that
- * command. Specifically, do not alter the way in which the command modifies
- * the registers. Otherwise backwards compatibility will suffer.
- */
-
-/* High-bandwidth backdoor port. --hpreg */
-
-#define BDOORHB_PORT 0x5659
-
-#define BDOORHB_CMD_MESSAGE 0
-#define BDOORHB_CMD_VASSERT 1
-#define BDOORHB_CMD_MAX 2
-
-/*
- * There is another backdoor which allows access to certain TSC-related
- * values using otherwise illegal PMC indices when the pseudo_perfctr
- * control flag is set.
- */
-
-#define BDOOR_PMC_HW_TSC 0x10000
-#define BDOOR_PMC_REAL_NS 0x10001
-#define BDOOR_PMC_APPARENT_NS 0x10002
-
-#define IS_BDOOR_PMC(index) (((index) | 3) == 0x10003)
-#define BDOOR_CMD(ecx) ((ecx) & 0xffff)
-
-
-#ifdef VMM
-/*
- *----------------------------------------------------------------------
- *
- * Backdoor_CmdRequiresFullyValidVCPU --
- *
- * A few backdoor commands require the full VCPU to be valid
- * (including GDTR, IDTR, TR and LDTR). The rest get read/write
- * access to GPRs and read access to Segment registers (selectors).
- *
- * Result:
- * True iff VECX contains a command that require the full VCPU to
- * be valid.
- *
- *----------------------------------------------------------------------
- */
-static INLINE Bool
-Backdoor_CmdRequiresFullyValidVCPU(unsigned cmd)
-{
- return cmd == BDOOR_CMD_RSVD0 ||
- cmd == BDOOR_CMD_RSVD1 ||
- cmd == BDOOR_CMD_RSVD2;
-}
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_COMPLETION_H__
-# define __COMPAT_COMPLETION_H__
-
-/*
- * The kernel's completion objects were made available for module use in 2.4.9.
- *
- * Between 2.4.0 and 2.4.9, we implement completions on our own using
- * waitqueues and counters. This was done so that we could safely support
- * functions like complete_all(), which cannot be implemented using semaphores.
- *
- * Prior to that, the waitqueue API is substantially different, and since none
- * of our modules that are built against older kernels need complete_all(),
- * we fallback on a simple semaphore-based implementation.
- */
-
-/*
- * Native completions.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#include <linux/completion.h>
-#define compat_completion struct completion
-#define compat_init_completion(comp) init_completion(comp)
-#define COMPAT_DECLARE_COMPLETION DECLARE_COMPLETION
-#define compat_wait_for_completion(comp) wait_for_completion(comp)
-#define compat_complete(comp) complete(comp)
-
-/* complete_all() was exported in 2.6.6. */
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
-# include "compat_wait.h"
-# include "compat_list.h"
-# include "compat_spinlock.h"
-# include "compat_sched.h"
-# define compat_complete_all(x) \
- ({ \
- struct list_head *currLinks; \
- spin_lock(&(x)->wait.lock); \
- (x)->done += UINT_MAX/2; \
- \
- list_for_each(currLinks, &(x)->wait.task_list) { \
- wait_queue_t *currQueue = list_entry(currLinks, wait_queue_t, task_list); \
- wake_up_process(currQueue->task); \
- } \
- spin_unlock(&(x)->wait.lock); \
- })
-# else
-# define compat_complete_all complete_all
-# endif
-
-/*
- * Completions via waitqueues.
- */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-
-/*
- * Kernel completions in 2.4.9 and beyond use a counter and a waitqueue, and
- * our implementation is quite similar. Because __wake_up_common() is not
- * exported, our implementations of compat_complete() and compat_complete_all()
- * are somewhat racy: the counter is incremented outside of the waitqueue's
- * lock.
- *
- * As a result, our completion cannot guarantee in-order wake ups. For example,
- * suppose thread A is entering compat_complete(), thread B is sleeping inside
- * compat_wait_for_completion(), and thread C is just now entering
- * compat_wait_for_completion(). If Thread A is scheduled first and increments
- * the counter, then gets swapped out, thread C may get scheduled and will
- * quickly go through compat_wait_for_completion() (since done != 0) while
- * thread B continues to sleep, even though thread B should have been the one
- * to wake up.
- */
-
-#include <asm/current.h>
-#include "compat_sched.h"
-#include "compat_list.h"
-#include <linux/smp_lock.h> // for lock_kernel()/unlock_kernel()
-#include "compat_wait.h"
-
-typedef struct compat_completion {
- unsigned int done;
- wait_queue_head_t wq;
-} compat_completion;
-
-#define compat_init_completion(comp) do { \
- (comp)->done = 0; \
- init_waitqueue_head(&(comp)->wq); \
-} while (0)
-#define COMPAT_DECLARE_COMPLETION(comp) \
- compat_completion comp = { \
- .done = 0, \
- .wq = __WAIT_QUEUE_HEAD_INITIALIZER((comp).wq), \
- }
-
-/*
- * Locking and unlocking the kernel lock here ensures that the thread
- * is no longer running in module code: compat_complete_and_exit
- * performs the sequence { lock_kernel(); up(comp); compat_exit(); }, with
- * the final unlock_kernel performed implicitly by the resident kernel
- * in do_exit.
- */
-#define compat_wait_for_completion(comp) do { \
- spin_lock_irq(&(comp)->wq.lock); \
- if (!(comp)->done) { \
- DECLARE_WAITQUEUE(wait, current); \
- wait.flags |= WQ_FLAG_EXCLUSIVE; \
- __add_wait_queue_tail(&(comp)->wq, &wait); \
- do { \
- __set_current_state(TASK_UNINTERRUPTIBLE); \
- spin_unlock_irq(&(comp)->wq.lock); \
- schedule(); \
- spin_lock_irq(&(comp)->wq.lock); \
- } while (!(comp)->done); \
- __remove_wait_queue(&(comp)->wq, &wait); \
- } \
- (comp)->done--; \
- spin_unlock_irq(&(comp)->wq.lock); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-/* XXX: I don't think I need to touch the BKL. */
-#define compat_complete(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done++; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up(&(comp)->wq); \
-} while (0)
-
-#define compat_complete_all(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done += UINT_MAX / 2; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up_all(&(comp)->wq); \
-} while (0)
-
-/*
- * Completions via semaphores.
- */
-#else
-
-#include "compat_semaphore.h"
-#define compat_completion struct semaphore
-#define compat_init_completion(comp) init_MUTEX_LOCKED(comp)
-#define COMPAT_DECLARE_COMPLETION(comp) DECLARE_MUTEX_LOCKED(comp)
-
-#define compat_wait_for_completion(comp) do { \
- down(comp); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-#define compat_complete(comp) up(comp)
-
-#endif
-
-#endif /* __COMPAT_COMPLETION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_FILE_H__
-# define __COMPAT_FILE_H__
-
-
-/* The fput() API is modified in 2.2.0 --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define compat_fput(_file) fput(_file)
-#else
-# define compat_fput(_file) fput(_file, (_file)->f_inode)
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-# define compat_get_file(_file) get_file(_file)
-# define compat_file_count(_file) file_count(_file)
-#else
-# define compat_get_file(_file) (_file)->f_count++
-# define compat_file_count(_file) (_file)->f_count
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 4)
-# define compat_filp_close(_file, _files) filp_close(_file, _files)
-#else
-static inline void compat_filp_close(struct file* filp, fl_owner_t files) {
- if (filp->f_op && filp->f_op->flush) {
- filp->f_op->flush(filp);
- }
- /*
- * Hopefully there are no locks to release on this filp.
- * locks_remove_posix is not exported so we cannot use it...
- */
- fput(filp);
-}
-#endif
-
-
-#endif /* __COMPAT_FILE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_KERNEL_H__
-# define __COMPAT_KERNEL_H__
-
-#include <asm/unistd.h>
-#include <linux/kernel.h>
-
-/*
- * container_of was introduced in 2.5.28 but it's easier to check like this.
- */
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-/*
- * wait_for_completion and friends did not exist before 2.4.9.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#define compat_complete_and_exit(comp, status) complete_and_exit(comp, status)
-
-#else
-
-#include "compat_completion.h"
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-#define __NR_compat_exit __NR_exit
-static inline _syscall1(int, compat_exit, int, exit_code);
-
-/*
- * See compat_wait_for_completion in compat_completion.h.
- * compat_exit implicitly performs an unlock_kernel, in resident code,
- * ensuring that the thread is no longer running in module code when the
- * module is unloaded.
- */
-#define compat_complete_and_exit(comp, status) do { \
- lock_kernel(); \
- compat_complete(comp); \
- compat_exit(status); \
-} while (0)
-
-#endif
-
-/*
- * vsnprintf became available in 2.4.10. For older kernels, just fall back on
- * vsprintf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define vsnprintf(str, size, fmt, args) vsprintf(str, fmt, args)
-#endif
-
-#endif /* __COMPAT_KERNEL_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_KTHREAD_H__
-# define __COMPAT_KTHREAD_H__
-
-/*
- * The kthread interface for managing kernel threads appeared in 2.6.4, but was
- * only exported for module use in 2.6.7.
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
-# include <linux/kthread.h>
-
-# define COMPAT_KTHREAD_DECLARE_STOP_INFO()
-# define compat_kthread_stop(_tsk) kthread_stop(_tsk)
-# define compat_kthread_should_stop() kthread_should_stop()
-# define compat_kthread_run(_fn, _data, _namefmt, ...) \
- kthread_run(_fn, _data, _namefmt, ## __VA_ARGS__)
-# define compat_kthread_create(_fn, _data, _namefmt, ...) \
- kthread_create(_fn, _data, _namefmt, ## __VA_ARGS__)
-#else
-
-/*
- * When the kthread interface isn't available, we do our best to emulate it,
- * with a few notable exceptions:
- *
- * 1: We use semaphores instead of mutexes for locking, because mutexes aren't
- * available in kernels where kthread isn't available.
- * 2: The real kthread interface uses the kthreadd kernel_thread to broker the
- * creation of new kernel threads. This makes sense because kthreadd is part
- * of the kernel, but doesn't make sense at all in the context of an
- * individual module. So in our emulation, thread creation occurs in the
- * context of a kthread_create call.
- * 3: Because kthreadd is responsible for creating kernel threads in the real
- * kthread interface, there's no need to explicitly reparent any of them. We
- * aren't using kthreadd, so we call daemonize to reparent, which also sets
- * the name of the new kernel thread. That's why we don't set the name as
- * the real kthread interface does (within kthread_create). Furthermore, to
- * get the name to daemonize, we're forced to pass it through the
- * kthread_start_info struct.
- * 4: Since our interface isn't in the kernel proper, we can't make use of
- * get_task_struct/put_task_struct so as to acquire references to kernel
- * threads that we're managing. To prevent races, we use an extra completion
- * when stopping kernel threads. See the comments in compat_kthread_stop for
- * more details.
- *
- * Like the real kthread interface, ours must be globally available so that we
- * can emulate functions like kthread_should_stop without using different
- * signatures.
- */
-
-# include "compat_completion.h"
-# include "compat_kernel.h"
-# include "compat_sched.h"
-
-struct compat_kthread_start_info {
- int (*fn)(void *);
- void *data;
- compat_completion created;
- char comm[TASK_COMM_LEN];
-};
-
-struct compat_kthread_stop_info {
- struct semaphore lock;
- struct task_struct *task;
- compat_completion woken;
- compat_completion stopped;
- int ret;
-};
-
-extern struct compat_kthread_stop_info compat_kthread_stop_info;
-
-# define COMPAT_KTHREAD_DECLARE_STOP_INFO() \
- struct compat_kthread_stop_info compat_kthread_stop_info = { \
- .lock = __SEMAPHORE_INITIALIZER(compat_kthread_stop_info.lock, 1), \
- .task = NULL, \
- }
-
-
-static inline int
-compat_kthread_should_stop(void)
-{
- return (compat_kthread_stop_info.task == current);
-}
-
-
-static inline int
-compat_kthread_stop(struct task_struct *_task)
-{
- int ret;
-
- down(&compat_kthread_stop_info.lock);
-
- /*
- * We use a write memory barrier to ensure that all CPUs see _task after
- * the completions have been initialized.
- *
- * There's a race between kernel threads managed by kthread and the upcoming
- * call to wake_up_process. If the kernel thread wakes up after we set task
- * but before the call to wake_up_process, the thread's call to
- * compat_kthread_should_stop will return true and the thread will exit. At
- * that point, the call to wake_up_process will be on a dead task_struct.
- *
- * XXX: The real kthread interface protects against this race by grabbing
- * and releasing a reference to _task. We don't have that luxury, because
- * there is a range of kernels where put_task_struct isn't exported to
- * modules. In fact, no other modules call get_task_struct or
- * put_task_struct, so to do so from this context may be unwise. Instead,
- * we'll use an extra completion to ensure that the kernel thread only exits
- * after wake_up_process has been called.
- */
- compat_init_completion(&compat_kthread_stop_info.woken);
- compat_init_completion(&compat_kthread_stop_info.stopped);
- smp_wmb();
-
- compat_kthread_stop_info.task = _task;
- wake_up_process(_task);
- compat_complete(&compat_kthread_stop_info.woken);
-
- compat_wait_for_completion(&compat_kthread_stop_info.stopped);
- compat_kthread_stop_info.task = NULL;
- ret = compat_kthread_stop_info.ret;
- up(&compat_kthread_stop_info.lock);
- return ret;
-}
-
-
-# define compat_kthread_run(_fn, _data, _namefmt, ...) \
-({ \
- struct task_struct *tsk; \
- tsk = compat_kthread_create(_fn, _data, _namefmt, ## __VA_ARGS__); \
- if (!IS_ERR(tsk)) { \
- wake_up_process(tsk); \
- } \
- tsk; \
-})
-
-
-static inline int
-compat_kthread(void *_data)
-{
- int ret = -EINTR;
- struct compat_kthread_start_info *info;
- int (*fn)(void *data);
- void *data;
-
- info = (struct compat_kthread_start_info *)_data;
- fn = info->fn;
- data = info->data;
-
- compat_daemonize(info->comm);
- __set_current_state(TASK_UNINTERRUPTIBLE);
- compat_complete(&info->created);
- schedule();
-
- if (!compat_kthread_should_stop()) {
- ret = fn(data);
- }
-
- if (compat_kthread_should_stop()) {
- compat_wait_for_completion(&compat_kthread_stop_info.woken);
- compat_kthread_stop_info.ret = ret;
- compat_complete_and_exit(&compat_kthread_stop_info.stopped, 0);
- BUG();
- }
- return 0;
-}
-
-
-static inline struct task_struct *
-compat_kthread_create(int (*_fn)(void *data),
- void *_data,
- const char _namefmt[],
- ...)
-{
- pid_t pid;
- struct task_struct *task = NULL;
- struct compat_kthread_start_info info;
- va_list args;
-
- info.fn = _fn;
- info.data = _data;
- compat_init_completion(&info.created);
- va_start(args, _namefmt);
- vsnprintf(info.comm, sizeof info.comm, _namefmt, args);
- va_end(args);
- pid = kernel_thread(compat_kthread, &info, CLONE_KERNEL);
- if (pid >= 0) {
- compat_wait_for_completion(&info.created);
-
- /*
- * find_task_by_pid must be called with tasklist_lock held or under
- * rcu_read_lock. As the latter doesn't exist in old kernels, we use the
- * former for convenience.
- */
- read_lock(&tasklist_lock);
- task = find_task_by_pid(pid);
- read_unlock(&tasklist_lock);
-
- /* XXX: Do we need to get a reference on task? */
- }
- return task;
-}
-
-#endif
-
-#endif /* __COMPAT_KTHREAD_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_LIST_H__
-# define __COMPAT_LIST_H__
-
-#include <linux/list.h>
-
-/*
- * list_add_tail is with us since 2.4.0, or something like that.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define list_add_tail(newe, head) do { \
- struct list_head *__h = (head); \
- __list_add((newe), __h->prev, __h); \
-} while (0)
-#endif
-
-/*
- * list_for_each_safe() showed up in 2.4.10, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_safe
-# define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-#endif
-
-/*
- * list_for_each_entry() showed up in 2.4.20, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_entry
-# define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-#endif
-
-#endif /* __COMPAT_LIST_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_MM_H__
-# define __COMPAT_MM_H__
-
-
-#include <linux/mm.h>
-
-
-/* The get_page() API appeared in 2.3.7 --hpreg */
-/* Sometime during development it became function instead of macro --petr */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(get_page)
-# define get_page(_page) atomic_inc(&(_page)->count)
-/* The __free_page() API is exported in 2.1.67 --hpreg */
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 67)
-# define put_page __free_page
-# else
-# include "compat_page.h"
-
-# define page_to_phys(_page) (page_to_pfn(_page) << PAGE_SHIFT)
-# define put_page(_page) free_page(page_to_phys(_page))
-# endif
-#endif
-
-
-/* page_count() is 2.4.0 invention. Unfortunately unavailable in some RedHat
- * kernels (for example 2.4.21-4-RHEL3). */
-/* It is function since 2.6.0, and hopefully RedHat will not play silly games
- * with mm_inline.h again... */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(page_count)
-# define page_count(page) atomic_read(&(page)->count)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-# define compat_vm_pgoff(vma) ((vma)->vm_offset >> PAGE_SHIFT)
-
-static inline unsigned long compat_do_mmap_pgoff(struct file *file, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long pgoff)
-{
- unsigned long ret = -EINVAL;
-
- if (pgoff < 1 << (32 - PAGE_SHIFT)) {
- ret = do_mmap(file, addr, len, prot, flag, pgoff << PAGE_SHIFT);
- }
- return ret;
-}
-
-#else
-# define compat_vm_pgoff(vma) (vma)->vm_pgoff
-# ifdef VMW_SKAS_MMAP
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(current->mm, f, a, l, p, g, o)
-# else
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(f, a, l, p, g, o)
-# endif
-#endif
-
-
-/* 2.2.x uses 0 instead of some define */
-#ifndef NOPAGE_SIGBUS
-#define NOPAGE_SIGBUS (0)
-#endif
-
-
-/* 2.2.x does not have HIGHMEM support */
-#ifndef GFP_HIGHUSER
-#define GFP_HIGHUSER (GFP_USER)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-
-#include "compat_page.h"
-
-static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
-{
- unsigned long addr;
-
- addr = __get_free_pages(gfp_mask, order);
- if (!addr) {
- return NULL;
- }
- return virt_to_page(addr);
-}
-#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
-
-#endif
-
-/*
- * In 2.4.14, the logic behind the UnlockPage macro was moved to the
- * unlock_page() function. Later (in 2.5.12), the UnlockPage macro was removed
- * altogether, and nowadays everyone uses unlock_page().
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 14)
-#define compat_unlock_page(page) UnlockPage(page)
-#else
-#define compat_unlock_page(page) unlock_page(page)
-#endif
-
-/*
- * In 2.4.10, vmtruncate was changed from returning void to returning int.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define compat_vmtruncate(inode, size) \
-({ \
- int result = 0; \
- vmtruncate(inode, size); \
- result; \
-})
-#else
-#define compat_vmtruncate(inode, size) vmtruncate(inode, size)
-#endif
-
-
-#endif /* __COMPAT_MM_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_PAGE_H__
-# define __COMPAT_PAGE_H__
-
-
-#include <linux/mm.h>
-#include <asm/page.h>
-
-
-/* The pfn_to_page() API appeared in 2.5.14 and changed to function during 2.6.x */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pfn_to_page)
-# define pfn_to_page(_pfn) (mem_map + (_pfn))
-# define page_to_pfn(_page) ((_page) - mem_map)
-#endif
-
-
-/* The virt_to_page() API appeared in 2.4.0 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(virt_to_page)
-# define virt_to_page(_kvAddr) pfn_to_page(MAP_NR(_kvAddr))
-#endif
-
-
-/*
- * The get_order() API appeared at some point in 2.3.x, and was then backported
- * in 2.2.17-21mdk and in the stock 2.2.18. Because we can only detect its
- * definition through makefile tricks, we provide our own for now --hpreg
- */
-static inline int
-compat_get_order(unsigned long size) // IN
-{
- int order;
-
- size = (size - 1) >> (PAGE_SHIFT - 1);
- order = -1;
- do {
- size >>= 1;
- order++;
- } while (size);
-
- return order;
-}
-
-/*
- * BUG() was added to <asm/page.h> in 2.2.18, and was moved to <asm/bug.h>
- * in 2.5.58.
- *
- * XXX: Technically, this belongs in some sort of "compat_asm_page.h" file, but
- * since our compatibility wrappers don't distinguish between <asm/xxx.h> and
- * <linux/xxx.h>, putting it here is reasonable.
- */
-#ifndef BUG
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- __asm__ __volatile__(".byte 0x0f,0x0b"); \
-} while (0)
-#endif
-
-#endif /* __COMPAT_PAGE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SCHED_H__
-# define __COMPAT_SCHED_H__
-
-
-#include <linux/sched.h>
-
-/* CLONE_KERNEL available in 2.5.35 and higher. */
-#ifndef CLONE_KERNEL
-#define CLONE_KERNEL CLONE_FILES | CLONE_FS | CLONE_SIGHAND
-#endif
-
-/* TASK_COMM_LEN become available in 2.6.11. */
-#ifndef TASK_COMM_LEN
-#define TASK_COMM_LEN 16
-#endif
-
-/* The capable() API appeared in 2.1.92 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 92)
-# define capable(_capability) suser()
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-# define need_resched() need_resched
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define need_resched() (current->need_resched)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define cond_resched() (need_resched() ? schedule() : (void) 0)
-#endif
-
-/* Oh well. We need yield... Happy us! */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
-# ifdef __x86_64__
-# define compat_yield() there_is_nothing_like_yield()
-# else
-# include <linux/unistd.h>
-# include <linux/kernel.h>
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-# define __NR_compat_yield __NR_sched_yield
-static inline _syscall0(int, compat_yield);
-# endif
-#else
-# define compat_yield() yield()
-#endif
-
-
-/*
- * Since 2.5.34 there are two methods to enumerate tasks:
- * for_each_process(p) { ... } which enumerates only tasks and
- * do_each_thread(g,t) { ... } while_each_thread(g,t) which enumerates
- * also threads even if they share same pid.
- */
-#ifndef for_each_process
-# define for_each_process(p) for_each_task(p)
-#endif
-
-#ifndef do_each_thread
-# define do_each_thread(g, t) for_each_task(g) { t = g; do
-# define while_each_thread(g, t) while (0) }
-#endif
-
-
-/*
- * Lock for signal mask is moving target...
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 40) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_sigmask_lock sigmask_lock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 60) && !defined(INIT_SIGHAND)
-/* RedHat's 2.4.x with first version of NPTL support, or 2.5.40 to 2.5.59 */
-#define compat_sigmask_lock sig->siglock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-/* RedHat's 2.4.x with second version of NPTL support, or 2.5.60+. */
-#define compat_sigmask_lock sighand->siglock
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(current, ¤t->blocked, (siginfo_ptr))
-#endif
-#endif
-
-/*
- * recalc_sigpending() had task argument in the past
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 29) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_recalc_sigpending() recalc_sigpending(current)
-#else
-/* RedHat's 2.4.x with NPTL support, or 2.5.29+ */
-#define compat_recalc_sigpending() recalc_sigpending()
-#endif
-
-
-/*
- * reparent_to_init() was introduced in 2.4.8. In 2.5.38 (or possibly
- * earlier, but later than 2.5.31) a call to it was added into
- * daemonize(), so compat_daemonize no longer needs to call it.
- *
- * In 2.4.x kernels reparent_to_init() forgets to do correct refcounting
- * on current->user. It is better to count one too many than one too few...
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 38)
-#define compat_reparent_to_init() do { \
- reparent_to_init(); \
- atomic_inc(¤t->user->__count); \
- } while (0)
-#else
-#define compat_reparent_to_init() do {} while (0)
-#endif
-
-
-/*
- * daemonize appeared in 2.2.18. Except 2.2.17-4-RH7.0, which has it too.
- * Fortunately 2.2.17-4-RH7.0 uses versioned symbols, so we can check
- * its existence with defined().
- */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) && !defined(daemonize)
-static inline void daemonize(void) {
- struct fs_struct *fs;
-
- exit_mm(current);
- current->session = 1;
- current->pgrp = 1;
- exit_fs(current);
- fs = init_task.fs;
- current->fs = fs;
- atomic_inc(&fs->count);
-}
-#endif
-
-
-/*
- * flush_signals acquires sighand->siglock since 2.5.61... Verify RH's kernels!
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_flush_signals(task) do { \
- spin_lock_irq(&task->compat_sigmask_lock); \
- flush_signals(task); \
- spin_unlock_irq(&task->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_flush_signals(task) flush_signals(task)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_allow_signal(signr) do { \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigdelset(¤t->blocked, signr); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_allow_signal(signr) allow_signal(signr)
-#endif
-
-/*
- * daemonize can set process name since 2.5.61. Prior to 2.5.61, daemonize
- * didn't block signals on our behalf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_daemonize(x...) \
-({ \
- /* Beware! No snprintf here, so verify arguments! */ \
- sprintf(current->comm, x); \
- \
- /* Block all signals. */ \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigfillset(¤t->blocked); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- compat_flush_signals(current); \
- \
- daemonize(); \
- compat_reparent_to_init(); \
-})
-#else
-#define compat_daemonize(x...) daemonize(x)
-#endif
-
-
-/*
- * set priority for specified thread. Exists on 2.6.x kernels and some
- * 2.4.x vendor's kernels.
- */
-#if defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) set_user_nice((task), (n))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define compat_set_user_nice(task, n) do { (task)->priority = 20 - (n); } while (0)
-#elif !defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) do { (task)->nice = (n); } while (0)
-#endif
-
-/*
- * try to freeze a process. For kernels 2.6.11 or newer, we know how to choose
- * the interface. The problem is that the oldest interface, introduced in
- * 2.5.18, was backported to 2.4.x kernels. So if we're older than 2.6.11,
- * we'll decide what to do based on whether or not swsusp was configured
- * for the kernel. For kernels 2.6.20 and newer, we'll also need to include
- * freezer.h since the try_to_freeze definition was pulled out of sched.h.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-#include <linux/freezer.h>
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) || defined(VMW_TL10S64_WORKAROUND)
-#define compat_try_to_freeze() try_to_freeze()
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
-#define compat_try_to_freeze() try_to_freeze(PF_FREEZE)
-#elif defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_SOFTWARE_SUSPEND2)
-#include "compat_mm.h"
-#include <linux/errno.h>
-#include <linux/suspend.h>
-static inline int compat_try_to_freeze(void) {
- if (current->flags & PF_FREEZE) {
- refrigerator(PF_FREEZE);
- return 1;
- } else {
- return 0;
- }
-}
-#else
-static inline int compat_try_to_freeze(void) { return 0; }
-#endif
-
-/*
- * As of 2.6.23-rc1, kernel threads are no longer freezable by
- * default. Instead, kernel threads that need to be frozen must opt-in
- * by calling set_freezable() as soon as the thread is created.
- */
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
-#define compat_set_freezable() do { set_freezable(); } while (0)
-#else
-#define compat_set_freezable() do {} while (0)
-#endif
-
-/*
- * Around 2.6.27 kernel stopped sending signals to kernel
- * threads being frozen, instead threads have to check
- * freezing() or use wait_event_freezable(). Unfortunately
- * wait_event_freezable() completely hides the fact that
- * thread was frozen from calling code and sometimes we do
- * want to know that.
- */
-#ifdef PF_FREEZER_NOSIG
-#define compat_wait_check_freezing() freezing(current)
-#else
-#define compat_wait_check_freezing() (0)
-#endif
-
-/*
- * Since 2.6.27-rc2 kill_proc() is gone... Replacement (GPL-only!)
- * API is available since 2.6.19. Use them from 2.6.27-rc1 up.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-typedef int compat_pid;
-#define compat_find_get_pid(pid) (pid)
-#define compat_put_pid(pid) do { } while (0)
-#define compat_kill_pid(pid, sig, flag) kill_proc(pid, sig, flag)
-#else
-typedef struct pid * compat_pid;
-#define compat_find_get_pid(pid) find_get_pid(pid)
-#define compat_put_pid(pid) put_pid(pid)
-#define compat_kill_pid(pid, sig, flag) kill_pid(pid, sig, flag)
-#endif
-
-
-#endif /* __COMPAT_SCHED_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SEMAPHORE_H__
-# define __COMPAT_SEMAPHORE_H__
-
-
-/* <= 2.6.25 have asm only, 2.6.26 has both, and 2.6.27-rc2+ has linux only. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-# include <asm/semaphore.h>
-#else
-# include <linux/semaphore.h>
-#endif
-
-
-/*
-* The init_MUTEX_LOCKED() API appeared in 2.2.18, and is also in
-* 2.2.17-21mdk --hpreg
-*/
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
- #ifndef init_MUTEX_LOCKED
- #define init_MUTEX_LOCKED(_sem) *(_sem) = MUTEX_LOCKED
- #endif
- #ifndef DECLARE_MUTEX
- #define DECLARE_MUTEX(name) struct semaphore name = MUTEX
- #endif
- #ifndef DECLARE_MUTEX_LOCKED
- #define DECLARE_MUTEX_LOCKED(name) struct semaphore name = MUTEX_LOCKED
- #endif
-#endif
-
-
-#endif /* __COMPAT_SEMAPHORE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SPINLOCK_H__
-# define __COMPAT_SPINLOCK_H__
-
-
-/*
- * The spin_lock() API appeared in 2.1.25 in asm/smp_lock.h
- * It moved in 2.1.30 to asm/spinlock.h
- * It moved again in 2.3.18 to linux/spinlock.h
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 18)
-# include <linux/spinlock.h>
-#else
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30)
-# include <asm/spinlock.h>
-# else
-typedef struct {} spinlock_t;
-# define spin_lock_init(lock)
-# define spin_lock(lock)
-# define spin_unlock(lock)
-# define spin_lock_irqsave(lock, flags) do { \
- save_flags(flags); \
- cli(); \
- spin_lock(lock); \
- } while (0)
-# define spin_unlock_irqrestore(lock, flags) do { \
- spin_unlock(lock); \
- restore_flags(flags); \
- } while (0)
-# endif
-#endif
-
-
-/*
- * Preempt support was added during 2.5.x development cycle, and later
- * it was backported to 2.4.x. In 2.4.x backport these definitions
- * live in linux/spinlock.h, that's why we put them here (in 2.6.x they
- * are defined in linux/preempt.h which is included by linux/spinlock.h).
- */
-#ifdef CONFIG_PREEMPT
-#define compat_preempt_disable() preempt_disable()
-#define compat_preempt_enable() preempt_enable()
-#else
-#define compat_preempt_disable() do { } while (0)
-#define compat_preempt_enable() do { } while (0)
-#endif
-
-
-#endif /* __COMPAT_SPINLOCK_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_WAIT_H__
-# define __COMPAT_WAIT_H__
-
-
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/file.h>
-
-#include "compat_file.h"
-
-
-/*
- * The DECLARE_WAITQUEUE() API appeared in 2.3.1
- * It was back ported in 2.2.18
- *
- * --hpreg
- */
-
-#ifndef DECLARE_WAITQUEUE
-
-typedef struct wait_queue *wait_queue_head_t;
-# define init_waitqueue_head(_headPtr) *(_headPtr) = NULL
-# define DECLARE_WAITQUEUE(_var, _task) \
- struct wait_queue _var = {_task, NULL, }
-
-typedef struct wait_queue wait_queue_t;
-# define init_waitqueue_entry(_wait, _task) ((_wait)->task = (_task))
-
-#endif
-
-/*
- * The 'struct poll_wqueues' appeared in 2.5.48, when global
- * /dev/epoll interface was added. It was backported to the
- * 2.4.20-wolk4.0s.
- */
-
-#ifdef VMW_HAVE_EPOLL // {
-#define compat_poll_wqueues struct poll_wqueues
-#else // } {
-#define compat_poll_wqueues poll_table
-#endif // }
-
-#ifdef VMW_HAVE_EPOLL // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- poll_initwait((table)), \
- (wait) = &(table)->pt \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), \
- poll_initwait(wait) \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#else // } {
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), /* confuse compiler */ \
- (wait) = (poll_table *) __get_free_page(GFP_KERNEL), \
- (wait)->nr = 0, \
- (wait)->entry = (struct poll_table_entry *)((wait) + 1), \
- (wait)->next = NULL \
-)
-
-static inline void
-poll_freewait(poll_table *wait)
-{
- while (wait) {
- struct poll_table_entry * entry;
- poll_table *old;
-
- entry = wait->entry + wait->nr;
- while (wait->nr > 0) {
- wait->nr--;
- entry--;
- remove_wait_queue(entry->wait_address, &entry->wait);
- compat_fput(entry->filp);
- }
- old = wait;
- wait = wait->next;
- free_page((unsigned long) old);
- }
-}
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((wait)) \
-)
-
-#endif // }
-
-/*
- * The wait_event_interruptible_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_interruptible_timeout
-#define __wait_event_interruptible_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_interruptible_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_interruptible_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * The wait_event_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_timeout
-#define __wait_event_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- if (condition) \
- break; \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * DEFINE_WAIT() and friends were added in 2.5.39 and backported to 2.4.28.
- *
- * Unfortunately it is not true. While some distros may have done it the
- * change has never made it into vanilla 2.4 kernel. Instead of testing
- * particular kernel versions let's just test for presence of DEFINE_WAIT
- * when figuring out whether we need to provide replacement implementation
- * or simply alias existing one.
- */
-
-#ifndef DEFINE_WAIT
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DECLARE_WAITQUEUE(_wait, current)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- add_wait_queue(_sleep, _wait); \
- } while (0)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- set_current_state(_state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- remove_wait_queue(_sleep, _wait); \
- } while (0)
-
-#else
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DEFINE_WAIT(_wait)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- finish_wait(_sleep, _wait)
-
-#endif /* #ifndef DEFINE_WAIT */
-
-#endif /* __COMPAT_WAIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * includeCheck.h --
- *
- * Restrict include file use.
- *
- * In every .h file, define one or more of these
- *
- * INCLUDE_ALLOW_VMX
- * INCLUDE_ALLOW_USERLEVEL
- * INCLUDE_ALLOW_VMMEXT
- * INCLUDE_ALLOW_VMCORE
- * INCLUDE_ALLOW_MODULE
- * INCLUDE_ALLOW_VMNIXMOD
- * INCLUDE_ALLOW_VMKERNEL
- * INCLUDE_ALLOW_DISTRIBUTE
- * INCLUDE_ALLOW_VMK_MODULE
- * INCLUDE_ALLOW_VMKDRIVERS
- * INCLUDE_ALLOW_VMIROM
- *
- * Then include this file.
- *
- * Any file that has INCLUDE_ALLOW_DISTRIBUTE defined will potentially
- * be distributed in source form along with GPLed code. Ensure
- * that this is acceptable.
- */
-
-
-/*
- * Declare a VMCORE-only variable to help classify object
- * files. The variable goes in the common block and does
- * not create multiple definition link-time conflicts.
- */
-
-#if defined VMCORE && defined VMX86_DEVEL && defined VMX86_DEBUG && \
- defined linux && !defined MODULE && \
- !defined COMPILED_WITH_VMCORE
-#define COMPILED_WITH_VMCORE compiled_with_vmcore
-#ifdef ASM
- .comm compiled_with_vmcore, 0
-#else
- asm(".comm compiled_with_vmcore, 0");
-#endif /* ASM */
-#endif
-
-
-#if defined VMCORE && \
- !(defined VMX86_VMX || defined VMM || \
- defined MONITOR_APP || defined VMMON)
-#error "Makefile problem: VMCORE without VMX86_VMX or \
- VMM or MONITOR_APP or MODULE."
-#endif
-
-#if defined VMCORE && !defined INCLUDE_ALLOW_VMCORE
-#error "The surrounding include file is not allowed in vmcore."
-#endif
-#undef INCLUDE_ALLOW_VMCORE
-
-#if defined VMX86_VMX && !defined VMCORE && \
- !(defined INCLUDE_ALLOW_VMX || defined INCLUDE_ALLOW_USERLEVEL)
-#error "The surrounding include file is not allowed in the VMX."
-#endif
-#undef INCLUDE_ALLOW_VMX
-
-#if defined USERLEVEL && !defined VMX86_VMX && !defined VMCORE && \
- !defined INCLUDE_ALLOW_USERLEVEL
-#error "The surrounding include file is not allowed at userlevel."
-#endif
-#undef INCLUDE_ALLOW_USERLEVEL
-
-#if defined VMM && !defined VMCORE && \
- !defined INCLUDE_ALLOW_VMMEXT
-#error "The surrounding include file is not allowed in the monitor."
-#endif
-#undef INCLUDE_ALLOW_VMMEXT
-
-#if defined MODULE && !defined VMKERNEL_MODULE && !defined VMNIXMOD && \
- !defined VMMON && !defined INCLUDE_ALLOW_MODULE
-#error "The surrounding include file is not allowed in driver modules."
-#endif
-#undef INCLUDE_ALLOW_MODULE
-
-#if defined VMMON && !defined INCLUDE_ALLOW_VMMON
-#error "The surrounding include file is not allowed in vmmon."
-#endif
-#undef INCLUDE_ALLOW_VMMON
-
-#if defined VMKERNEL && !defined INCLUDE_ALLOW_VMKERNEL
-#error "The surrounding include file is not allowed in the vmkernel."
-#endif
-#undef INCLUDE_ALLOW_VMKERNEL
-
-#if defined GPLED_CODE && !defined INCLUDE_ALLOW_DISTRIBUTE
-#error "The surrounding include file is not allowed in GPL code."
-#endif
-#undef INCLUDE_ALLOW_DISTRIBUTE
-
-#if defined VMKERNEL_MODULE && !defined VMKERNEL && \
- !defined INCLUDE_ALLOW_VMK_MODULE && !defined INCLUDE_ALLOW_VMKDRIVERS
-#error "The surrounding include file is not allowed in vmkernel modules."
-#endif
-#undef INCLUDE_ALLOW_VMK_MODULE
-#undef INCLUDE_ALLOW_VMKDRIVERS
-
-#if defined VMNIXMOD && !defined INCLUDE_ALLOW_VMNIXMOD
-#ifndef VMNIXMOD_VM
-#error "The surrounding include file is not allowed in vmnixmod."
-#endif
-#endif
-#undef INCLUDE_ALLOW_VMNIXMOD
-
-#if defined VMIROM && ! defined INCLUDE_ALLOW_VMIROM
-#error "The surrounding include file is not allowed in vmirom."
-#endif
-#undef INCLUDE_ALLOW_VMIROM
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_assert.h --
- *
- * The basic assertion facility for all VMware code.
- *
- * For proper use, see
- * http://vmweb.vmware.com/~mts/WebSite/guide/programming/asserts.html
- */
-
-#ifndef _VM_ASSERT_H_
-#define _VM_ASSERT_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-// XXX not necessary except some places include vm_assert.h improperly
-#include "vm_basic_types.h"
-#include "vm_basic_defs.h"
-
-
-/*
- * XXX old file code
- */
-
-#ifdef FILECODEINT
-#error "Don't define FILECODEINT. It is obsolete."
-#endif
-#ifdef FILECODE
-#error "Don't define FILECODE. It is obsolete."
-#endif
-
-
-/*
- * Panic and log functions
- */
-
-EXTERN void Log(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN void Warning(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2);
-
-EXTERN void LogThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-EXTERN void WarningThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-
-/* DB family: messages which are parsed by logfile database system */
-#define WarningDB Warning
-#define LogDB Log
-#define WarningThrottledDB WarningThrottled
-#define LogThrottledDB LogThrottled
-
-
-/*
- * Stress testing: redefine ASSERT_IFNOT() to taste
- */
-
-#ifndef ASSERT_IFNOT
- /*
- * PR 271512: When compiling with gcc, catch assignments inside an ASSERT.
- *
- * 'UNLIKELY' is defined with __builtin_expect, which does not warn when passed an
- * assignment (gcc bug 36050).
- * To get around this, we put 'cond' in an 'if' statement and make sure it never gets
- * executed by putting that inside of 'if (0)'.
- * We use gcc's statement expression syntax to make ASSERT an expression because some
- * code uses it that way.
- *
- * Since statement expression syntax is a gcc extension and since it's not clear if
- * this is a problem with other compilers, the ASSERT definition was not changed for
- * them. Using a bare 'cond' with the ternary operator may provide a solution.
- */
- #ifdef __GNUC__
- #define ASSERT_IFNOT(cond, panic) \
- ({if (UNLIKELY(!(cond))) { panic; if (0) { if (cond) { ; } } } (void)0;})
- #else
- #define ASSERT_IFNOT(cond, panic) \
- (UNLIKELY(!(cond)) ? (panic) : (void)0)
- #endif
-#endif
-
-
-/*
- * Assert, panic, and log macros
- *
- * Some of these are redefined below undef !VMX86_DEBUG.
- * ASSERT() is special cased because of interaction with Windows DDK.
- */
-
-#if defined VMX86_DEBUG || defined ASSERT_ALWAYS_AVAILABLE
-#undef ASSERT
-#define ASSERT(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertAssert))
-#endif
-#define ASSERT_BUG(bug, cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC_BUG(bug, AssertAssert))
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ASSERT_BUG(bug, cond)
-
-#define PANIC() _ASSERT_PANIC(AssertPanic)
-#define PANIC_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertPanic)
-
-#define ASSERT_NOT_IMPLEMENTED(cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED())
-#define ASSERT_NOT_IMPLEMENTED_BUG(bug, cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED_BUG(bug))
-
-#define NOT_IMPLEMENTED() _ASSERT_PANIC(AssertNotImplemented)
-#define NOT_IMPLEMENTED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotImplemented)
-
-#define NOT_REACHED() _ASSERT_PANIC(AssertNotReached)
-#define NOT_REACHED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotReached)
-
-#define ASSERT_MEM_ALLOC(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertMemAlloc))
-
-#ifdef VMX86_DEVEL
- #define ASSERT_LENGTH(real, expected) \
- ASSERT_IFNOT((real) == (expected), \
- Panic(AssertLengthFmt, __FILE__, __LINE__, real, expected))
-#else
- #define ASSERT_LENGTH(real, expected) ASSERT((real) == (expected))
-#endif
-
-#ifdef VMX86_DEVEL
- #define ASSERT_DEVEL(cond) ASSERT(cond)
-#else
- #define ASSERT_DEVEL(cond) ((void) 0)
-#endif
-
-#define ASSERT_NO_INTERRUPTS() ASSERT(!INTERRUPTS_ENABLED())
-#define ASSERT_HAS_INTERRUPTS() ASSERT(INTERRUPTS_ENABLED())
-
-#define ASSERT_LOG_UNEXPECTED(bug, cond) \
- (UNLIKELY(!(cond)) ? LOG_UNEXPECTED(bug) : 0)
-#ifdef VMX86_DEVEL
- #define LOG_UNEXPECTED(bug) \
- Warning(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#else
- #define LOG_UNEXPECTED(bug) \
- Log(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#endif
-
-#define ASSERT_NOT_TESTED(cond) (UNLIKELY(!(cond)) ? NOT_TESTED() : 0)
-#ifdef VMX86_DEVEL
- #define NOT_TESTED() Warning(AssertNotTestedFmt, __FILE__, __LINE__)
-#else
- #define NOT_TESTED() Log(AssertNotTestedFmt, __FILE__, __LINE__)
-#endif
-
-#define NOT_TESTED_ONCE() \
- do { \
- static Bool alreadyPrinted = FALSE; \
- if (UNLIKELY(!alreadyPrinted)) { \
- alreadyPrinted = TRUE; \
- NOT_TESTED(); \
- } \
- } while (0)
-
-#define NOT_TESTED_1024() \
- do { \
- static uint16 count = 0; \
- if (UNLIKELY(count == 0)) { NOT_TESTED(); } \
- count = (count + 1) & 1023; \
- } while (0)
-
-#define LOG_ONCE(_s) \
- do { \
- static Bool logged = FALSE; \
- if (!logged) { \
- Log _s; \
- logged = TRUE; \
- } \
- } while (0)
-
-
-/*
- * Redefine macros that are only in debug versions
- */
-
-#if !defined VMX86_DEBUG && !defined ASSERT_ALWAYS_AVAILABLE // {
-
-#undef ASSERT
-#define ASSERT(cond) ((void) 0)
-
-#undef ASSERT_BUG_DEBUGONLY
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ((void) 0)
-
-#undef ASSERT_LENGTH
-#define ASSERT_LENGTH(real, expected) ((void) 0)
-
-/*
- * Expand NOT_REACHED() as appropriate for each situation.
- *
- * Mainly, we want the compiler to infer the same control-flow
- * information as it would from Panic(). Otherwise, different
- * compilation options will lead to different control-flow-derived
- * errors, causing some make targets to fail while others succeed.
- *
- * VC++ has the __assume() built-in function which we don't trust
- * (see bug 43485); gcc has no such construct; we just panic in
- * userlevel code. The monitor doesn't want to pay the size penalty
- * (measured at 212 bytes for the release vmm for a minimal infinite
- * loop; panic would cost even more) so it does without and lives
- * with the inconsistency.
- */
-
-#ifdef VMM
-#undef NOT_REACHED
-#define NOT_REACHED() ((void) 0)
-#else
-// keep debug definition
-#endif
-
-#undef ASSERT_LOG_UNEXPECTED
-#define ASSERT_LOG_UNEXPECTED(bug, cond) ((void) 0)
-
-#undef LOG_UNEXPECTED
-#define LOG_UNEXPECTED(bug) ((void) 0)
-
-#undef ASSERT_NOT_TESTED
-#define ASSERT_NOT_TESTED(cond) ((void) 0)
-#undef NOT_TESTED
-#define NOT_TESTED() ((void) 0)
-#undef NOT_TESTED_ONCE
-#define NOT_TESTED_ONCE() ((void) 0)
-#undef NOT_TESTED_1024
-#define NOT_TESTED_1024() ((void) 0)
-
-#endif // !VMX86_DEBUG }
-
-
-/*
- * Compile-time assertions.
- *
- * ASSERT_ON_COMPILE does not use the common
- * switch (0) { case 0: case (e): ; } trick because some compilers (e.g. MSVC)
- * generate code for it.
- *
- * The implementation uses both enum and typedef because the typedef alone is
- * insufficient; gcc allows arrays to be declared with non-constant expressions
- * (even in typedefs, where it makes no sense).
- */
-
-#define ASSERT_ON_COMPILE(e) \
- do { \
- enum { AssertOnCompileMisused = ((e) ? 1 : -1) }; \
- typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \
- } while (0)
-
-
-/*
- * To put an ASSERT_ON_COMPILE() outside a function, wrap it
- * in MY_ASSERTS(). The first parameter must be unique in
- * each .c file where it appears. For example,
- *
- * MY_ASSERTS(FS3_INT,
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLock) == 128);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLockReserved) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskBlock) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(Hardware_DMIUUID) == 16);
- * )
- *
- * Caution: ASSERT() within MY_ASSERTS() is silently ignored.
- * The same goes for anything else not evaluated at compile time.
- */
-
-#define MY_ASSERTS(name, assertions) \
- static INLINE void name(void) { \
- assertions \
- }
-
-
-/*
- * Internal macros, functions, and strings
- *
- * The monitor wants to save space at call sites, so it has specialized
- * functions for each situation. User level wants to save on implementation
- * so it uses generic functions.
- */
-
-#if !defined VMM || defined MONITOR_APP // {
-
-#define _ASSERT_PANIC(name) \
- Panic(_##name##Fmt "\n", __FILE__, __LINE__)
-#define _ASSERT_PANIC_BUG(bug, name) \
- Panic(_##name##Fmt " bugNr=%d\n", __FILE__, __LINE__, bug)
-
-#define AssertLengthFmt _AssertLengthFmt
-#define AssertUnexpectedFmt _AssertUnexpectedFmt
-#define AssertNotTestedFmt _AssertNotTestedFmt
-
-#endif // }
-
-// these don't have newline so a bug can be tacked on
-#define _AssertPanicFmt "PANIC %s:%d"
-#define _AssertAssertFmt "ASSERT %s:%d"
-#define _AssertNotImplementedFmt "NOT_IMPLEMENTED %s:%d"
-#define _AssertNotReachedFmt "NOT_REACHED %s:%d"
-#define _AssertMemAllocFmt "MEM_ALLOC %s:%d"
-
-// these are complete formats with newline
-#define _AssertLengthFmt "LENGTH %s:%d r=%#x e=%#x\n"
-#define _AssertUnexpectedFmt "UNEXPECTED %s:%d bugNr=%d\n"
-#define _AssertNotTestedFmt "NOT_TESTED %s:%d\n"
-
-#endif /* ifndef _VM_ASSERT_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_defs.h --
- *
- * Standard macros for VMware source code.
- */
-
-#ifndef _VM_BASIC_DEFS_H_
-#define _VM_BASIC_DEFS_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-#include "vm_basic_types.h" // For INLINE.
-
-/* Checks for FreeBSD, filtering out VMKERNEL. */
-#define __IS_FREEBSD__ (!defined(VMKERNEL) && defined(__FreeBSD__))
-#define __IS_FREEBSD_VER__(ver) (__IS_FREEBSD__ && __FreeBSD_version >= (ver))
-
-#if defined _WIN32 && defined USERLEVEL
- #include <stddef.h> /*
- * We re-define offsetof macro from stddef, make
- * sure that its already defined before we do it
- */
- #include <windows.h> // for Sleep() and LOWORD() etc.
-#endif
-
-
-/*
- * Simple macros
- */
-
-#if (defined __APPLE__ || defined __FreeBSD__) && \
- (!defined KERNEL && !defined _KERNEL && !defined VMKERNEL && !defined __KERNEL__)
-# include <stddef.h>
-#else
-// XXX the _WIN32 one matches that of VC++, to prevent redefinition warning
-// XXX the other one matches that of gcc3.3.3/glibc2.2.4 to prevent redefinition warnings
-#ifndef offsetof
-#ifdef _WIN32
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-#endif
-#endif // __APPLE__
-
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(a) (sizeof (a) / sizeof *(a))
-#endif
-
-#ifndef MIN
-#define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
-#endif
-
-/* The Solaris 9 cross-compiler complains about these not being used */
-#ifndef sun
-static INLINE int
-Min(int a, int b)
-{
- return a < b ? a : b;
-}
-#endif
-
-#ifndef MAX
-#define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
-#endif
-
-#ifndef sun
-static INLINE int
-Max(int a, int b)
-{
- return a > b ? a : b;
-}
-#endif
-
-#define ROUNDUP(x,y) (((x) + (y) - 1) / (y) * (y))
-#define ROUNDDOWN(x,y) ((x) / (y) * (y))
-#define ROUNDUPBITS(x, bits) (((uintptr_t) (x) + MASK(bits)) & ~MASK(bits))
-#define ROUNDDOWNBITS(x, bits) ((uintptr_t) (x) & ~MASK(bits))
-#define CEILING(x, y) (((x) + (y) - 1) / (y))
-#if defined __APPLE__
-#include <machine/param.h>
-#undef MASK
-#endif
-#define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */
-#define DWORD_ALIGN(x) ((((x)+3) >> 2) << 2)
-#define QWORD_ALIGN(x) ((((x)+4) >> 3) << 3)
-
-#define IMPLIES(a,b) (!(a) || (b))
-
-/*
- * Not everybody (e.g., the monitor) has NULL
- */
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *)0)
-#endif
-#endif
-
-
-/*
- * Token concatenation
- *
- * The C preprocessor doesn't prescan arguments when they are
- * concatenated or stringified. So we need extra levels of
- * indirection to convince the preprocessor to expand its
- * arguments.
- */
-
-#define CONC(x, y) x##y
-#define XCONC(x, y) CONC(x, y)
-#define XXCONC(x, y) XCONC(x, y)
-#define MAKESTR(x) #x
-#define XSTR(x) MAKESTR(x)
-
-
-/*
- * Page operations
- *
- * It has been suggested that these definitions belong elsewhere
- * (like x86types.h). However, I deem them common enough
- * (since even regular user-level programs may want to do
- * page-based memory manipulation) to be here.
- * -- edward
- */
-
-#ifndef PAGE_SHIFT // {
-#if defined VM_I386
- #define PAGE_SHIFT 12
-#elif defined __APPLE__
- #define PAGE_SHIFT 12
-#else
- #error
-#endif
-#endif // }
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE (1<<PAGE_SHIFT)
-#endif
-
-#ifndef PAGE_MASK
-#define PAGE_MASK (PAGE_SIZE - 1)
-#endif
-
-#ifndef PAGE_OFFSET
-#define PAGE_OFFSET(_addr) ((uintptr_t)(_addr)&(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGE_BASE
-#define VM_PAGE_BASE(_addr) ((_addr)&~(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGES_SPANNED
-#define VM_PAGES_SPANNED(_addr, _size) \
- ((((_addr) & (PAGE_SIZE - 1)) + (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
-#endif
-
-#ifndef BYTES_2_PAGES
-#define BYTES_2_PAGES(_nbytes) ((_nbytes) >> PAGE_SHIFT)
-#endif
-
-#ifndef PAGES_2_BYTES
-#define PAGES_2_BYTES(_npages) (((uint64)(_npages)) << PAGE_SHIFT)
-#endif
-
-#ifndef MBYTES_2_PAGES
-#define MBYTES_2_PAGES(_nbytes) ((_nbytes) << (20 - PAGE_SHIFT))
-#endif
-
-#ifndef PAGES_2_MBYTES
-#define PAGES_2_MBYTES(_npages) ((_npages) >> (20 - PAGE_SHIFT))
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SHIFT
-#define VM_PAE_LARGE_PAGE_SHIFT 21
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SIZE
-#define VM_PAE_LARGE_PAGE_SIZE (1 << VM_PAE_LARGE_PAGE_SHIFT)
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_MASK
-#define VM_PAE_LARGE_PAGE_MASK (VM_PAE_LARGE_PAGE_SIZE - 1)
-#endif
-
-#ifndef VM_PAE_LARGE_2_SMALL_PAGES
-#define VM_PAE_LARGE_2_SMALL_PAGES (BYTES_2_PAGES(VM_PAE_LARGE_PAGE_SIZE))
-#endif
-
-/*
- * Word operations
- */
-
-#ifndef LOWORD
-#define LOWORD(_dw) ((_dw) & 0xffff)
-#endif
-#ifndef HIWORD
-#define HIWORD(_dw) (((_dw) >> 16) & 0xffff)
-#endif
-
-#ifndef LOBYTE
-#define LOBYTE(_w) ((_w) & 0xff)
-#endif
-#ifndef HIBYTE
-#define HIBYTE(_w) (((_w) >> 8) & 0xff)
-#endif
-
-#define HIDWORD(_qw) ((uint32)((_qw) >> 32))
-#define LODWORD(_qw) ((uint32)(_qw))
-#define QWORD(_hi, _lo) ((((uint64)(_hi)) << 32) | ((uint32)(_lo)))
-
-
-/*
- * Deposit a field _src at _pos bits from the right,
- * with a length of _len, into the integer _target.
- */
-
-#define DEPOSIT_BITS(_src,_pos,_len,_target) { \
- unsigned mask = ((1 << _len) - 1); \
- unsigned shiftedmask = ((1 << _len) - 1) << _pos; \
- _target = (_target & ~shiftedmask) | ((_src & mask) << _pos); \
-}
-
-
-/*
- * Get return address.
- */
-
-#ifdef _MSC_VER
-#ifdef __cplusplus
-extern "C"
-#endif
-void *_ReturnAddress(void);
-#pragma intrinsic(_ReturnAddress)
-#define GetReturnAddress() _ReturnAddress()
-#elif __GNUC__
-#define GetReturnAddress() __builtin_return_address(0)
-#endif
-
-
-#ifdef __GNUC__
-#ifndef sun
-
-/*
- * Get the frame pointer. We use this assembly hack instead of
- * __builtin_frame_address() due to a bug introduced in gcc 4.1.1
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetFrameAddr(void)
-{
- uintptr_t bp;
-#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0))
- bp = (uintptr_t)__builtin_frame_address(0);
-#elif (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 3)
-# if defined(VMM64) || defined(VM_X86_64)
- __asm__ __volatile__("movq %%rbp, %0\n" : "=g" (bp));
-# else
- __asm__ __volatile__("movl %%ebp, %0\n" : "=g" (bp));
-# endif
-#else
- __asm__ __volatile__(
-#ifdef __linux__
- ".print \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
- ".abort"
-#else /* MacOS */
- ".abort \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
-#endif
- : "=g" (bp)
- );
-#endif
- return bp;
-}
-
-
-/*
- * Returns the frame pointer of the calling function.
- * Equivalent to __builtin_frame_address(1).
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetCallerFrameAddr(void)
-{
- return *(uintptr_t*)GetFrameAddr();
-}
-
-#endif // sun
-#endif // __GNUC__
-
-/*
- * Data prefetch was added in gcc 3.1.1
- * http://www.gnu.org/software/gcc/gcc-3.1/changes.html
- */
-#ifdef __GNUC__
-# if ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 1) || \
- (__GNUC__ == 3 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 1))
-# define PREFETCH_R(var) __builtin_prefetch((var), 0 /* read */, \
- 3 /* high temporal locality */)
-# define PREFETCH_W(var) __builtin_prefetch((var), 1 /* write */, \
- 3 /* high temporal locality */)
-# else
-# define PREFETCH_R(var) ((void)(var))
-# define PREFETCH_W(var) ((void)(var))
-# endif
-#endif /* __GNUC__ */
-
-
-#ifdef USERLEVEL // {
-
-/*
- * Note this might be a problem on NT b/c while sched_yield guarantees it
- * moves you to the end of your priority list, Sleep(0) offers no such
- * guarantee. Bummer. --Jeremy.
- */
-
-#if defined(N_PLAT_NLM)
-/* We do not have YIELD() as we do not need it yet... */
-#elif defined(_WIN32)
-# define YIELD() Sleep(0)
-#else
-# include <sched.h> // For sched_yield. Don't ask. --Jeremy.
-# define YIELD() sched_yield()
-#endif
-
-
-/*
- * Standardize some Posix names on Windows.
- */
-
-#ifdef _WIN32 // {
-
-#define snprintf _snprintf
-#define strtok_r strtok_s
-
-#if (_MSC_VER < 1500)
-#define vsnprintf _vsnprintf
-#endif
-
-typedef int uid_t;
-typedef int gid_t;
-
-static INLINE void
-sleep(unsigned int sec)
-{
- Sleep(sec * 1000);
-}
-
-static INLINE void
-usleep(unsigned long usec)
-{
- Sleep(CEILING(usec, 1000));
-}
-
-typedef int pid_t;
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-#define R_OK 4
-
-#endif // }
-
-/*
- * Macro for username comparison.
- */
-
-#ifdef _WIN32 // {
-#define USERCMP(x,y) Str_Strcasecmp(x,y)
-#else
-#define USERCMP(x,y) strcmp(x,y)
-#endif // }
-
-
-#endif // }
-
-#ifndef va_copy
-
-#ifdef _WIN32
-
-/*
- * Windows needs va_copy. This works for both 32 and 64-bit Windows
- * based on inspection of how varags.h from the Visual C CRTL is
- * implemented. (Future versions of the RTL may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__APPLE__) && defined(KERNEL)
-
-/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__GNUC__) && (__GNUC__ < 3)
-
-/*
- * Old versions of gcc recognize __va_copy, but not va_copy.
- */
-
-#define va_copy(dest, src) __va_copy(dest, src)
-
-#endif // _WIN32
-
-#endif // va_copy
-
-/*
- * This one is outside USERLEVEL because it's used by
- * files compiled into the Windows hgfs driver or the display
- * driver.
- */
-
-#ifdef _WIN32
-#define PATH_MAX 256
-#ifndef strcasecmp
-#define strcasecmp(_s1,_s2) _stricmp((_s1),(_s2))
-#endif
-#ifndef strncasecmp
-#define strncasecmp(_s1,_s2,_n) _strnicmp((_s1),(_s2),(_n))
-#endif
-#endif
-
-/*
- * Convenience macro for COMMUNITY_SOURCE
- */
-#undef EXCLUDE_COMMUNITY_SOURCE
-#ifdef COMMUNITY_SOURCE
- #define EXCLUDE_COMMUNITY_SOURCE(x)
-#else
- #define EXCLUDE_COMMUNITY_SOURCE(x) x
-#endif
-
-#undef COMMUNITY_SOURCE_INTEL_SECRET
-#if !defined(COMMUNITY_SOURCE) || defined(INTEL_SOURCE)
-/*
- * It's ok to include INTEL_SECRET source code for non-commsrc,
- * or for drops directed at Intel.
- */
- #define COMMUNITY_SOURCE_INTEL_SECRET
-#endif
-
-/*
- * Convenience macros and definitions. Can often be used instead of #ifdef.
- */
-
-#undef DEBUG_ONLY
-#undef SL_DEBUG_ONLY
-#undef VMX86_SL_DEBUG
-#ifdef VMX86_DEBUG
-#define vmx86_debug 1
-#define DEBUG_ONLY(x) x
-/*
- * Be very, very, very careful with SL_DEBUG. Pls ask ganesh or min before
- * using it.
- */
-#define VMX86_SL_DEBUG
-#define vmx86_sl_debug 1
-#define SL_DEBUG_ONLY(x) x
-#else
-#define vmx86_debug 0
-#define DEBUG_ONLY(x)
-#define vmx86_sl_debug 0
-#define SL_DEBUG_ONLY(x)
-#endif
-
-#ifdef VMX86_STATS
-#define vmx86_stats 1
-#define STATS_ONLY(x) x
-#else
-#define vmx86_stats 0
-#define STATS_ONLY(x)
-#endif
-
-#ifdef VMX86_DEVEL
-#define vmx86_devel 1
-#define DEVEL_ONLY(x) x
-#else
-#define vmx86_devel 0
-#define DEVEL_ONLY(x)
-#endif
-
-#ifdef VMX86_LOG
-#define vmx86_log 1
-#define LOG_ONLY(x) x
-#else
-#define vmx86_log 0
-#define LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_VMM_SERIAL_LOGGING
-#define vmx86_vmm_serial_log 1
-#define VMM_SERIAL_LOG_ONLY(x) x
-#else
-#define vmx86_vmm_serial_log 0
-#define VMM_SERIAL_LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_SERVER
-#define vmx86_server 1
-#define SERVER_ONLY(x) x
-#define HOSTED_ONLY(x)
-#else
-#define vmx86_server 0
-#define SERVER_ONLY(x)
-#define HOSTED_ONLY(x) x
-#endif
-
-#ifdef VMX86_WGS
-#define vmx86_wgs 1
-#define WGS_ONLY(x) x
-#else
-#define vmx86_wgs 0
-#define WGS_ONLY(x)
-#endif
-
-#ifdef VMKERNEL
-#define vmkernel 1
-#define VMKERNEL_ONLY(x) x
-#else
-#define vmkernel 0
-#define VMKERNEL_ONLY(x)
-#endif
-
-#ifdef _WIN32
-#define WIN32_ONLY(x) x
-#define POSIX_ONLY(x)
-#else
-#define WIN32_ONLY(x)
-#define POSIX_ONLY(x) x
-#endif
-
-#ifdef VMM
-#define VMM_ONLY(x) x
-#define USER_ONLY(x)
-#else
-#define VMM_ONLY(x)
-#define USER_ONLY(x) x
-#endif
-
-/* VMVISOR ifdef only allowed in the vmkernel */
-#ifdef VMKERNEL
-#ifdef VMVISOR
-#define vmvisor 1
-#define VMVISOR_ONLY(x) x
-#else
-#define vmvisor 0
-#define VMVISOR_ONLY(x)
-#endif
-#endif
-
-#ifdef _WIN32
-#define VMW_INVALID_HANDLE INVALID_HANDLE_VALUE
-#else
-#define VMW_INVALID_HANDLE (-1)
-#endif
-
-#ifdef _WIN32
-#define fsync(fd) _commit(fd)
-#define fileno(f) _fileno(f)
-#else
-#endif
-
-/*
- * Debug output macros for Windows drivers (the Eng variant is for
- * display/printer drivers only.
- */
-#ifdef _WIN32
-#ifndef USES_OLD_WINDDK
-#if defined(VMX86_DEBUG) || defined(ASSERT_ALWAYS_AVAILABLE)
-#define WinDrvPrint(arg, ...) DbgPrint(arg, __VA_ARGS__)
-#define WinDrvEngPrint(arg, ...) EngDbgPrint(arg, __VA_ARGS__)
-#else
-#define WinDrvPrint(arg, ...)
-#define WinDrvEngPrint(arg, ...)
-#endif
-#endif
-#endif // _WIN32
-
-#endif // ifndef _VM_BASIC_DEFS_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- *
- * vm_basic_types.h --
- *
- * basic data types.
- */
-
-
-#ifndef _VM_BASIC_TYPES_H_
-#define _VM_BASIC_TYPES_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-/* STRICT ANSI means the Xserver build and X defines Bool differently. */
-#if !defined(__STRICT_ANSI__) || defined(__FreeBSD__)
-typedef char Bool;
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define IsBool(x) (((x) & ~1) == 0)
-#define IsBool2(x, y) ((((x) | (y)) & ~1) == 0)
-
-/*
- * Macros __i386__ and __ia64 are intrinsically defined by GCC
- */
-#ifdef __i386__
-#define VM_I386
-#endif
-
-#ifdef _WIN64
-#define __x86_64__
-#endif
-
-#ifdef __x86_64__
-#define VM_X86_64
-#define VM_I386
-#define vm_x86_64 (1)
-#else
-#define vm_x86_64 (0)
-#endif
-
-
-
-#ifdef _WIN32
-/* safe assumption for a while */
-#define VM_I386
-#endif
-
-#ifdef _MSC_VER
-
-#pragma warning (3 :4505) // unreferenced local function
-#pragma warning (disable :4018) // signed/unsigned mismatch
-#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
-#pragma warning (disable :4305) // truncation from 'const int' to 'short'
-#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
-#pragma warning (disable :4267) // truncation of 'size_t'
-#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
-#pragma warning (disable :4142) // benign redefinition of type
-
-#endif
-
-#if defined(__APPLE__) || defined(HAVE_STDINT_H)
-
-/*
- * TODO: This is a C99 standard header. We should be able to test for
- * #if __STDC_VERSION__ >= 199901L, but that breaks the Netware build
- * (which doesn't have stdint.h).
- */
-
-#include <stdint.h>
-
-typedef uint64_t uint64;
-typedef int64_t int64;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint8_t uint8;
-
-/*
- * XXX: int8_t is defined to be 'signed char' on Mac hosts.
- *
- * Unfortunately, GCC 4.0.1 warns when doing pointer assignment or
- * comparison between signed char * and char * (even if char is
- * signed).
- *
- * If we want to use int8_t to define int8, we need to go through and
- * replace uses of char * with signed char * to prevent warnings.
- */
-typedef char int8;
-
-#else /* !HAVE_STDINT_H */
-
-#ifdef _MSC_VER
-
-typedef unsigned __int64 uint64;
-typedef signed __int64 int64;
-
-#elif __GNUC__
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-#if defined(VM_X86_64)
-typedef unsigned long uint64;
-typedef long int64;
-#else
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#elif __FreeBSD__
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#else
-#error - Need compiler define for int64/uint64
-#endif /* _MSC_VER */
-
-typedef unsigned int uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
-typedef int int32;
-typedef short int16;
-typedef char int8;
-
-#endif /* HAVE_STDINT_H */
-
-/*
- * FreeBSD (for the tools build) unconditionally defines these in
- * sys/inttypes.h so don't redefine them if this file has already
- * been included. [greg]
- *
- * This applies to Solaris as well.
- */
-
-/*
- * Before trying to do the includes based on OS defines, see if we can use
- * feature-based defines to get as much functionality as possible
- */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_INTTYPES_H
-#include <sys/inttypes.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
-#endif
-
-#if !defined(USING_AUTOCONF)
-# if defined(__FreeBSD__) || defined(sun)
-# ifdef KLD_MODULE
-# include <sys/types.h>
-# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
-# include <sys/types.h>
-# else
-# include <sys/inttypes.h>
-# endif
-# endif
-# elif defined __APPLE__
-# if KERNEL
-# include <sys/unistd.h>
-# include <sys/types.h> /* mostly for size_t */
-# include <stdint.h>
-# else
-# include <unistd.h>
-# include <inttypes.h>
-# include <stdlib.h>
-# include <stdint.h>
-# endif
-# else
-# if !defined(__intptr_t_defined) && !defined(intptr_t)
-# define __intptr_t_defined
-# define intptr_t intptr_t
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef int64 intptr_t;
-# else
-typedef int32 intptr_t;
-# endif
-# endif
-# endif
-
-# ifndef _STDINT_H
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef uint64 uintptr_t;
-# else
-typedef uint32 uintptr_t;
-# endif
-# endif
-# endif
-# endif
-#endif
-
-
-/*
- * Time
- * XXX These should be cleaned up. -- edward
- */
-
-typedef int64 VmTimeType; /* Time in microseconds */
-typedef int64 VmTimeRealClock; /* Real clock kept in microseconds */
-typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */
-
-/*
- * Printf format specifiers for size_t and 64-bit number.
- * Use them like this:
- * printf("%"FMT64"d\n", big);
- *
- * FMTH is for handles/fds.
- */
-
-#ifdef _MSC_VER
- #define FMT64 "I64"
- #ifdef VM_X86_64
- #define FMTSZ "I64"
- #define FMTPD "I64"
- #define FMTH "I64"
- #else
- #define FMTSZ "I"
- #define FMTPD "I"
- #define FMTH "I"
- #endif
-#elif defined __APPLE__
- /* Mac OS hosts use the same formatters for 32- and 64-bit. */
- #define FMT64 "ll"
- #define FMTSZ "z"
- #define FMTPD "l"
- #define FMTH ""
-#elif __GNUC__
- #define FMTH ""
- #if defined(N_PLAT_NLM) || defined(sun) || \
- (defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) < 5))
- /*
- * Why (__FreeBSD__ + 0)? See bug 141008.
- * Yes, we really need to test both (__FreeBSD__ + 0) and
- * ((__FreeBSD__ + 0) < 5). No, we can't remove "+ 0" from
- * ((__FreeBSD__ + 0) < 5).
- */
- #ifdef VM_X86_64
- #define FMTSZ "l"
- #define FMTPD "l"
- #else
- #define FMTSZ ""
- #define FMTPD ""
- #endif
- #elif defined(__linux__) \
- || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
- || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
- || (defined(_POSIX2_VERSION) && _POSIX2_VERSION >= 200112L)
- /* BSD, Linux */
- #define FMTSZ "z"
-
- #if defined(VM_X86_64)
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #else
- /* Systems with a pre-C99 libc */
- #define FMTSZ "Z"
- #ifdef VM_X86_64
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #endif
- #ifdef VM_X86_64
- #define FMT64 "l"
- #elif defined(sun) || defined(__FreeBSD__)
- #define FMT64 "ll"
- #else
- #define FMT64 "L"
- #endif
-#else
- #error - Need compiler define for FMT64 and FMTSZ
-#endif
-
-/*
- * Suffix for 64-bit constants. Use it like this:
- * CONST64(0x7fffffffffffffff) for signed or
- * CONST64U(0x7fffffffffffffff) for unsigned.
- *
- * 2004.08.30(thutt):
- * The vmcore/asm64/gen* programs are compiled as 32-bit
- * applications, but must handle 64 bit constants. If the
- * 64-bit-constant defining macros are already defined, the
- * definition will not be overwritten.
- */
-
-#if !defined(CONST64) || !defined(CONST64U)
-#ifdef _MSC_VER
-#define CONST64(c) c##I64
-#define CONST64U(c) c##uI64
-#elif defined __APPLE__
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#elif __GNUC__
-#ifdef VM_X86_64
-#define CONST64(c) c##L
-#define CONST64U(c) c##uL
-#else
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#endif
-#else
-#error - Need compiler define for CONST64
-#endif
-#endif
-
-/*
- * Use CONST3264/CONST3264U if you want a constant to be
- * treated as a 32-bit number on 32-bit compiles and
- * a 64-bit number on 64-bit compiles. Useful in the case
- * of shifts, like (CONST3264U(1) << x), where x could be
- * more than 31 on a 64-bit compile.
- */
-
-#ifdef VM_X86_64
- #define CONST3264(a) CONST64(a)
- #define CONST3264U(a) CONST64U(a)
-#else
- #define CONST3264(a) (a)
- #define CONST3264U(a) (a)
-#endif
-
-#define MIN_INT32 ((int32)0x80000000)
-#define MAX_INT32 ((int32)0x7fffffff)
-
-#define MIN_UINT32 ((uint32)0)
-#define MAX_UINT32 ((uint32)0xffffffff)
-
-#define MIN_INT64 (CONST64(0x8000000000000000))
-#define MAX_INT64 (CONST64(0x7fffffffffffffff))
-
-#define MIN_UINT64 (CONST64U(0))
-#define MAX_UINT64 (CONST64U(0xffffffffffffffff))
-
-typedef uint8 *TCA; /* Pointer into TC (usually). */
-
-/*
- * Type big enough to hold an integer between 0..100
- */
-typedef uint8 Percent;
-#define AsPercent(v) ((Percent)(v))
-#define CHOOSE_PERCENT AsPercent(101)
-
-
-typedef uintptr_t VA;
-typedef uintptr_t VPN;
-
-typedef uint64 PA;
-typedef uint32 PPN;
-
-typedef uint64 PhysMemOff;
-typedef uint64 PhysMemSize;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 BA;
-#endif
-typedef uint32 BPN;
-typedef uint32 PageNum;
-typedef unsigned MemHandle;
-typedef int32 World_ID;
-
-#define INVALID_WORLD_ID ((World_ID)-1)
-
-typedef World_ID User_CartelID;
-#define INVALID_CARTEL_ID INVALID_WORLD_ID
-
-typedef User_CartelID User_SessionID;
-#define INVALID_SESSION_ID INVALID_CARTEL_ID
-
-typedef User_CartelID User_CartelGroupID;
-#define INVALID_CARTELGROUP_ID INVALID_CARTEL_ID
-
-typedef uint32 Worldlet_ID;
-#define INVALID_WORLDLET_ID ((Worldlet_ID)-1)
-
-/* world page number */
-typedef uint32 WPN;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 MA;
-typedef uint32 MPN;
-#endif
-
-/*
- * This type should be used for variables that contain sector
- * position/quantity.
- */
-typedef uint64 SectorType;
-
-/*
- * Linear address
- */
-
-typedef uintptr_t LA;
-typedef uintptr_t LPN;
-#define LA_2_LPN(_la) ((_la) >> PAGE_SHIFT)
-#define LPN_2_LA(_lpn) ((_lpn) << PAGE_SHIFT)
-
-#define LAST_LPN ((((LA) 1) << (8 * sizeof(LA) - PAGE_SHIFT)) - 1)
-#define LAST_LPN32 ((((LA32)1) << (8 * sizeof(LA32) - PAGE_SHIFT)) - 1)
-#define LAST_LPN64 ((((LA64)1) << (8 * sizeof(LA64) - PAGE_SHIFT)) - 1)
-
-/* Valid bits in a LPN. */
-#define LPN_MASK LAST_LPN
-#define LPN_MASK32 LAST_LPN32
-#define LPN_MASK64 LAST_LPN64
-
-/*
- * On 64 bit platform, address and page number types default
- * to 64 bit. When we need to represent a 32 bit address, we use
- * types defined below.
- *
- * On 32 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint32 VA32;
-typedef uint32 VPN32;
-typedef uint32 LA32;
-typedef uint32 LPN32;
-typedef uint32 PA32;
-typedef uint32 PPN32;
-typedef uint32 MA32;
-typedef uint32 MPN32;
-
-/*
- * On 64 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint64 VA64;
-typedef uint64 VPN64;
-typedef uint64 LA64;
-typedef uint64 LPN64;
-typedef uint64 PA64;
-typedef uint64 PPN64;
-typedef uint64 MA64;
-typedef uint64 MPN64;
-
-/*
- * VA typedefs for user world apps.
- */
-typedef VA32 UserVA32;
-typedef VA64 UserVA64;
-typedef UserVA64 UserVAConst; /* Userspace ptr to data that we may only read. */
-typedef UserVA32 UserVA32Const; /* Userspace ptr to data that we may only read. */
-typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */
-#ifdef VMKERNEL
-typedef UserVA64 UserVA;
-#else
-typedef void * UserVA;
-#endif
-
-
-/*
- * Maximal possible PPN value (errors too) that PhysMem can handle.
- * Must be at least as large as MAX_PPN which is the maximum PPN
- * for any region other than buserror.
- */
-#define PHYSMEM_MAX_PPN ((PPN)0xffffffff)
-#define MAX_PPN ((PPN)0x1fffffff) /* Maximal observable PPN value. */
-#define INVALID_PPN ((PPN)0xffffffff)
-
-#define INVALID_BPN ((BPN) 0x1fffffff)
-
-#define INVALID_MPN ((MPN)-1)
-#define MEMREF_MPN ((MPN)-2)
-#define RESERVED_MPN ((MPN) 0)
-/* Support 43 bits of address space. */
-#define MAX_MPN ((MPN)0x7fffffff)
-
-#define INVALID_LPN ((LPN)-1)
-#define INVALID_VPN ((VPN)-1)
-#define INVALID_LPN64 ((LPN64)-1)
-#define INVALID_PAGENUM ((PageNum)-1)
-#define INVALID_WPN ((WPN) -1)
-
-
-/*
- * Format modifier for printing VA, LA, and VPN.
- * Use them like this: Log("%#"FMTLA"x\n", laddr)
- */
-
-#if defined(VMM64) || defined(FROBOS64) || vm_x86_64 || defined __APPLE__
-# define FMTLA "l"
-# define FMTVA "l"
-# define FMTVPN "l"
-#else
-# define FMTLA ""
-# define FMTVA ""
-# define FMTVPN ""
-#endif
-
-#ifndef EXTERN
-#define EXTERN extern
-#endif
-#define CONST const
-
-
-#ifndef INLINE
-# ifdef _MSC_VER
-# define INLINE __inline
-# else
-# define INLINE inline
-# endif
-#endif
-
-
-/*
- * Annotation for data that may be exported into a DLL and used by other
- * apps that load that DLL and import the data.
- */
-#if defined(_WIN32) && defined(VMX86_IMPORT_DLLDATA)
-# define VMX86_EXTERN_DATA extern __declspec(dllimport)
-#else // !_WIN32
-# define VMX86_EXTERN_DATA extern
-#endif
-
-#if defined(_WIN32) && !defined(VMX86_NO_THREADS)
-#define THREADSPECIFIC __declspec(thread)
-#else
-#define THREADSPECIFIC
-#endif
-
-/*
- * Due to the wonderful "registry redirection" feature introduced in
- * 64-bit Windows, if you access any key under HKLM\Software in 64-bit
- * code, you need to open/create/delete that key with
- * VMKEY_WOW64_32KEY if you want a consistent view with 32-bit code.
- */
-
-#ifdef _WIN32
-#ifdef _WIN64
-#define VMW_KEY_WOW64_32KEY KEY_WOW64_32KEY
-#else
-#define VMW_KEY_WOW64_32KEY 0x0
-#endif
-#endif
-
-
-/*
- * Consider the following reasons functions are inlined:
- *
- * 1) inlined for performance reasons
- * 2) inlined because it's a single-use function
- *
- * Functions which meet only condition 2 should be marked with this
- * inline macro; It is not critical to be inlined (but there is a
- * code-space & runtime savings by doing so), so when other callers
- * are added the inline-ness should be removed.
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-/*
- * Starting at version 3.3, gcc does not always inline functions marked
- * 'inline' (it depends on their size). To force gcc to do so, one must use the
- * extra __always_inline__ attribute.
- */
-# define INLINE_SINGLE_CALLER INLINE __attribute__((__always_inline__))
-# if defined(VMM) \
- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
-# warning Verify INLINE_SINGLE_CALLER '__always_inline__' attribute (did \
- monitor size change?)
-# endif
-#else
-# define INLINE_SINGLE_CALLER INLINE
-#endif
-
-/*
- * Used when a hard guaranteed of no inlining is needed. Very few
- * instances need this since the absence of INLINE is a good hint
- * that gcc will not do inlining.
- */
-
-#if defined(__GNUC__) && defined(VMM)
-#define ABSOLUTELY_NOINLINE __attribute__((__noinline__))
-#endif
-
-/*
- * Attributes placed on function declarations to tell the compiler
- * that the function never returns.
- */
-
-#ifdef _MSC_VER
-#define NORETURN __declspec(noreturn)
-#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9)
-#define NORETURN __attribute__((__noreturn__))
-#else
-#define NORETURN
-#endif
-
-/*
- * GCC 3.2 inline asm needs the + constraint for input/ouput memory operands.
- * Older GCCs don't know about it --hpreg
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
-# define VM_ASM_PLUS 1
-#else
-# define VM_ASM_PLUS 0
-#endif
-
-/*
- * Branch prediction hints:
- * LIKELY(exp) - Expression exp is likely TRUE.
- * UNLIKELY(exp) - Expression exp is likely FALSE.
- * Usage example:
- * if (LIKELY(excCode == EXC_NONE)) {
- * or
- * if (UNLIKELY(REAL_MODE(vc))) {
- *
- * We know how to predict branches on gcc3 and later (hopefully),
- * all others we don't so we do nothing.
- */
-
-#if (__GNUC__ >= 3)
-/*
- * gcc3 uses __builtin_expect() to inform the compiler of an expected value.
- * We use this to inform the static branch predictor. The '!!' in LIKELY
- * will convert any !=0 to a 1.
- */
-#define LIKELY(_exp) __builtin_expect(!!(_exp), 1)
-#define UNLIKELY(_exp) __builtin_expect((_exp), 0)
-#else
-#define LIKELY(_exp) (_exp)
-#define UNLIKELY(_exp) (_exp)
-#endif
-
-/*
- * GCC's argument checking for printf-like functions
- * This is conditional until we have replaced all `"%x", void *'
- * with `"0x%08x", (uint32) void *'. Note that %p prints different things
- * on different platforms. Argument checking is enabled for the
- * vmkernel, which has already been cleansed.
- *
- * fmtPos is the position of the format string argument, beginning at 1
- * varPos is the position of the variable argument, beginning at 1
- */
-
-#if defined(__GNUC__)
-# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
-#else
-# define PRINTF_DECL(fmtPos, varPos)
-#endif
-
-#if defined(__GNUC__)
-# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
-#else
-# define SCANF_DECL(fmtPos, varPos)
-#endif
-
-/*
- * UNUSED_PARAM should surround the parameter name and type declaration,
- * e.g. "int MyFunction(int var1, UNUSED_PARAM(int var2))"
- *
- */
-
-#ifndef UNUSED_PARAM
-# if defined(__GNUC__)
-# define UNUSED_PARAM(_parm) _parm __attribute__((__unused__))
-# else
-# define UNUSED_PARAM(_parm) _parm
-# endif
-#endif
-
-/*
- * REGPARM defaults to REGPARM3, i.e., a requent that gcc
- * puts the first three arguments in registers. (It is fine
- * if the function has fewer than three args.) Gcc only.
- * Syntactically, put REGPARM where you'd put INLINE or NORETURN.
- */
-
-#if defined(__GNUC__)
-# define REGPARM0 __attribute__((regparm(0)))
-# define REGPARM1 __attribute__((regparm(1)))
-# define REGPARM2 __attribute__((regparm(2)))
-# define REGPARM3 __attribute__((regparm(3)))
-# define REGPARM REGPARM3
-#else
-# define REGPARM0
-# define REGPARM1
-# define REGPARM2
-# define REGPARM3
-# define REGPARM
-#endif
-
-/*
- * ALIGNED specifies minimum alignment in "n" bytes.
- */
-
-#ifdef __GNUC__
-#define ALIGNED(n) __attribute__((__aligned__(n)))
-#else
-#define ALIGNED(n)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_OFFSET_CHECK -- */ /**
- *
- * \brief Check if the actual offsef of a member in a structure
- * is what is expected
- *
- *
- * \param[in] STRUCT Structure the member is a part of.
- * \param[in] MEMBER Member to check the offset of.
- * \param[in] OFFSET Expected offset of MEMBER in STRUCTURE.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to OFFSET to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == (OFFSET + DEBUG_EXTRA))
-#else
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == OFFSET)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_SIZE_CHECK -- */ /**
- *
- * \brief Check if the actual size of a structure is what is expected
- *
- *
- * \param[in] STRUCT Structure whose size is to be checked.
- * \param[in] SIZE Expected size of STRUCT.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to SIZE to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == (SIZE + DEBUG_EXTRA))
-#else
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == SIZE)
-#endif
-
-/*
- * __func__ is a stringified function name that is part of the C99 standard. The block
- * below defines __func__ on older systems where the compiler does not support that
- * macro.
- */
-#if defined(__GNUC__) \
- && ((__GNUC__ == 2 && __GNUC_MINOR < 96) \
- || (__GNUC__ < 2))
-# define __func__ __FUNCTION__
-#endif
-
-/*
- * Once upon a time, this was used to silence compiler warnings that
- * get generated when the compiler thinks that a function returns
- * when it is marked noreturn. Don't do it. Use NOT_REACHED().
- */
-
-#define INFINITE_LOOP() do { } while (1)
-
-/*
- * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_
- * is defined. Use the same logic here so we don't define it twice. [greg]
- */
-#ifdef __FreeBSD__
-# ifdef _BSD_SIZE_T_
-# undef _BSD_SIZE_T_
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# ifdef _BSD_SSIZE_T_
-# undef _BSD_SSIZE_T_
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#else
-# ifndef _SIZE_T
-# define _SIZE_T
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(ssize_t) && \
- !defined(__ssize_t_defined) && !defined(_SSIZE_T_DECLARED)
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#endif
-
-/*
- * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The pid is %"FMTPID".\n", pid);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTPID "d"
-# else
-# define FMTPID "lu"
-# endif
-#else
-# define FMTPID "d"
-#endif
-
-/*
- * Format modifier for printing uid_t. On Solaris 10 and earlier, uid_t
- * is a ulong, but on other platforms it's an unsigned int.
- * Use this like this: printf("The uid is %"FMTUID".\n", uid);
- */
-#if defined(sun) && !defined(SOL11)
-# ifdef VM_X86_64
-# define FMTUID "u"
-# else
-# define FMTUID "lu"
-# endif
-#else
-# define FMTUID "u"
-#endif
-
-/*
- * Format modifier for printing mode_t. On sun the mode_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The mode is %"FMTMODE".\n", mode);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTMODE "o"
-# else
-# define FMTMODE "lo"
-# endif
-#else
-# define FMTMODE "o"
-#endif
-
-/*
- * Format modifier for printing time_t. Most platforms define a time_t to be
- * a long int, but on FreeBSD (as of 5.0, it seems), the time_t is a signed
- * size quantity. Refer to the definition of FMTSZ to see why we need silly
- * preprocessor arithmetic.
- * Use this like this: printf("The mode is %"FMTTIME".\n", time);
- */
-#if defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) >= 5)
-# define FMTTIME FMTSZ"d"
-#else
-# define FMTTIME "ld"
-#endif
-
-/*
- * Define MXSemaHandle here so both vmmon and vmx see this definition.
- */
-
-#ifdef _WIN32
-typedef uintptr_t MXSemaHandle;
-#else
-typedef int MXSemaHandle;
-#endif
-
-/*
- * Define type for poll device handles.
- */
-
-#ifdef _WIN32
-typedef uintptr_t PollDevHandle;
-#else
-typedef int PollDevHandle;
-#endif
-
-/*
- * Define the utf16_t type.
- */
-
-#if defined(_WIN32) && defined(_NATIVE_WCHAR_T_DEFINED)
-typedef wchar_t utf16_t;
-#else
-typedef uint16 utf16_t;
-#endif
-
-#endif /* _VM_BASIC_TYPES_H_ */
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmsync
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#### VMware vmsync Makefile to be distributed externally
####
-INCLUDE := -I.
+INCLUDE += -I.
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachecreate.c, -DVMW_KMEMCR_HAS_DTOR, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, )
obj-m += $(DRIVER).o
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * All kernels before 2.6.22 take 6 arguments. All kernels since
- * 2.6.23-rc1 take 5 arguments. Only kernels between 2.6.22 and
- * 2.6.23-rc1 are questionable - we could ignore them if we wanted,
- * nobody cares about them even now. But unfortunately RedHat is
- * re-releasing 2.6.X-rc kernels under 2.6.(X-1) name, so they
- * are releasing 2.6.23-rc1 as 2.6.22-5055-something, so we have
- * to do autodetection for them.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
-/* Success... */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#error "This test intentionally fails on 2.6.23 and newer kernels."
-#else
-#include <linux/slab.h>
-
-struct kmem_cache *kmemtest(void) {
- return kmem_cache_create("test", 12, 0, 0, NULL, NULL);
-}
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * Between 2.6.23 and 2.6.24-rc1 ctor prototype was changed from
- * ctor(ptr, cache, flags) to ctor(cache, ptr). Unfortunately there
- * is no typedef for ctor, so we have to redefine kmem_cache_create
- * to find out ctor prototype. This assumes that kmem_cache_create
- * takes 5 arguments and not 6 - that change occured between
- * 2.6.22 and 2.6.23-rc1. If prototype matches, then this is old
- * kernel.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-#error "This test intentionally fails on 2.6.24 and newer kernels."
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#include <linux/slab.h>
-
-struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
- unsigned long,
- void (*)(void *, struct kmem_cache *, unsigned long));
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * Between 2.6.27-rc1 and 2.6.27-rc2 ctor prototype was changed from
- * ctor(cache, ptr) to ctor(ptr). Unfortunately there
- * is no typedef for ctor, so we have to redefine kmem_cache_create
- * to find out ctor prototype. If prototype matches, then this is old
- * kernel.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-#error "This test intentionally fails on 2.6.28 and newer kernels."
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
-#include <linux/slab.h>
-
-struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
- unsigned long,
- void (*)(struct kmem_cache *, void *));
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_FS_H__
-# define __COMPAT_FS_H__
-
-#include <linux/fs.h>
-
-/*
- * 2.6.5+ kernels define FS_BINARY_MOUNTDATA. Since it didn't exist and
- * wasn't used prior, it's safe to define it to zero.
- */
-
-#ifndef FS_BINARY_MOUNTDATA
-#define FS_BINARY_MOUNTDATA 0
-#endif
-
-/*
- * MAX_LFS_FILESIZE wasn't defined until 2.5.4.
- */
-#ifndef MAX_LFS_FILESIZE
-# include <linux/pagemap.h>
-# if BITS_PER_LONG == 32
-# define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG - 1)) - 1)
-# elif BITS_PER_LONG == 64
-# define MAX_LFS_FILESIZE 0x7fffffffffffffffUL
-# endif
-#endif
-
-
-/*
- * sendfile as a VFS op was born in 2.5.30. Unfortunately, it also changed
- * signatures, first in 2.5.47, then again in 2.5.70, then again in 2.6.8.
- * Luckily, the 2.6.8+ signature is the same as the 2.5.47 signature. And
- * as of 2.6.23-rc1 sendfile is gone, replaced by splice_read...
- *
- * Let's not support sendfile from 2.5.30 to 2.5.47, because the 2.5.30
- * signature is much different and file_send_actor isn't externed.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#define VMW_SENDFILE_NONE
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
-#define VMW_SENDFILE_NEW
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 70)
-#define VMW_SENDFILE_OLD
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 47)
-#define VMW_SENDFILE_NEW
-#else
-#define VMW_SENDFILE_NONE
-#endif
-
-/*
- * splice_read is there since 2.6.17, but let's avoid 2.6.17-rcX kernels...
- * After all nobody is using splice system call until 2.6.23 using it to
- * implement sendfile.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
-#define VMW_SPLICE_READ 1
-#endif
-
-/*
- * Filesystems wishing to use generic page cache read/write routines are
- * supposed to implement aio_read and aio_write (calling into
- * generic_file_aio_read() and generic_file_aio_write() if necessary).
- *
- * The VFS exports do_sync_read() and do_sync_write() as the "new"
- * generic_file_read() and generic_file_write(), but filesystems need not
- * actually implement read and write- the VFS will automatically call
- * do_sync_write() and do_sync_read() when applications invoke the standard
- * read() and write() system calls.
- *
- * In 2.6.19, generic_file_read() and generic_file_write() were removed,
- * necessitating this change. AIO dates as far back as 2.5.42, but the API has
- * changed over time, so for simplicity, we'll only enable it from 2.6.19 and
- * on.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
-# define VMW_USE_AIO
-#endif
-
-
-/*
- * The alloc_inode and destroy_inode VFS ops didn't exist prior to 2.4.21.
- * Without these functions, file systems can't embed inodes.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 21)
-# define VMW_EMBED_INODE
-#endif
-
-
-/*
- * iget() was removed from the VFS as of 2.6.25-rc1. The replacement for iget()
- * is iget_locked() which was added in 2.5.17.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 17)
-# define VMW_USE_IGET_LOCKED
-#endif
-
-/*
- * parent_ino was born in 2.5.5. For older kernels, let's use 2.5.5
- * implementation. It uses the dcache lock which is OK because per-dentry
- * locking appeared after 2.5.5.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-#define compat_parent_ino(dentry) parent_ino(dentry)
-#else
-#define compat_parent_ino(dentry) \
-({ \
- ino_t res; \
- spin_lock(&dcache_lock); \
- res = dentry->d_parent->d_inode->i_ino; \
- spin_unlock(&dcache_lock); \
- res; \
-})
-#endif
-
-
-/*
- * putname changed to __putname in 2.6.6.
- */
-#define compat___getname() __getname()
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
-#define compat___putname(name) putname(name)
-#else
-#define compat___putname(name) __putname(name)
-#endif
-
-
-/*
- * inc_nlink, drop_nlink, and clear_nlink were added in 2.6.19.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#define compat_inc_nlink(inode) ((inode)->i_nlink++)
-#define compat_drop_nlink(inode) ((inode)->i_nlink--)
-#define compat_clear_nlink(inode) ((inode)->i_nlink = 0)
-#else
-#define compat_inc_nlink(inode) inc_nlink(inode)
-#define compat_drop_nlink(inode) drop_nlink(inode)
-#define compat_clear_nlink(inode) clear_nlink(inode)
-#endif
-
-
-/*
- * i_size_write and i_size_read were introduced in 2.6.0-test1
- * (though we'll look for them as of 2.6.1). They employ slightly different
- * locking in order to guarantee atomicity, depending on the length of a long,
- * whether the kernel is SMP, or whether the kernel is preemptible. Prior to
- * i_size_write and i_size_read, there was no such locking, so that's the
- * behavior we'll emulate.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 1)
-#define compat_i_size_read(inode) ((inode)->i_size)
-#define compat_i_size_write(inode, size) ((inode)->i_size = size)
-#else
-#define compat_i_size_read(inode) i_size_read(inode)
-#define compat_i_size_write(inode, size) i_size_write(inode, size)
-#endif
-
-
-/*
- * filemap_fdatawrite was introduced in 2.5.12. Prior to that, modules used
- * filemap_fdatasync instead. In 2.4.18, both filemap_fdatawrite and
- * filemap_fdatawait began returning status codes. Prior to that, they were
- * void functions, so we'll just have them return 0.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 18)
-#define compat_filemap_fdatawrite(mapping) \
-({ \
- int result = 0; \
- filemap_fdatasync(mapping); \
- result; \
-})
-#define compat_filemap_fdatawait(mapping) \
-({ \
- int result = 0; \
- filemap_fdatawait(mapping); \
- result; \
-})
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12)
-#define compat_filemap_fdatawrite(mapping) filemap_fdatasync(mapping)
-#define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping)
-#else
-#define compat_filemap_fdatawrite(mapping) filemap_fdatawrite(mapping)
-#define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping)
-#endif
-
-
-/*
- * filemap_write_and_wait was introduced in 2.6.6 and exported for module use
- * in 2.6.16. It's really just a simple wrapper around filemap_fdatawrite and
- * and filemap_fdatawait, which initiates a flush of all dirty pages, then
- * waits for the pages to flush. The implementation here is a simplified form
- * of the one found in 2.6.20-rc3.
- *
- * Unfortunately, it just isn't possible to implement this prior to 2.4.5, when
- * neither filemap_fdatawait nor filemap_fdatasync were exported for module
- * use. So we'll define it out and hope for the best.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 5)
-#define compat_filemap_write_and_wait(mapping)
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
-#define compat_filemap_write_and_wait(mapping) \
-({ \
- int result = 0; \
- if (mapping->nrpages) { \
- result = compat_filemap_fdatawrite(mapping); \
- if (result != -EIO) { \
- int result2 = compat_filemap_fdatawait(mapping); \
- if (!result) { \
- result = result2; \
- } \
- } \
- } \
- result; \
-})
-#else
-#define compat_filemap_write_and_wait(mapping) filemap_write_and_wait(mapping)
-#endif
-
-
-/*
- * invalidate_remote_inode was introduced in 2.6.0-test5. Prior to that,
- * filesystems wishing to invalidate pages belonging to an inode called
- * invalidate_inode_pages.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-#define compat_invalidate_remote_inode(inode) invalidate_inode_pages(inode)
-#else
-#define compat_invalidate_remote_inode(inode) invalidate_remote_inode(inode)
-#endif
-
-#endif /* __COMPAT_FS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_NAMEI_H__
-# define __COMPAT_NAMEI_H__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18)
-#include <linux/namei.h>
-#endif
-
-/*
- * In 2.6.25-rc2, dentry and mount objects were removed from the nameidata
- * struct. They were both replaced with a struct path.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
-#define compat_vmw_nd_to_dentry(nd) (nd).path.dentry
-#else
-#define compat_vmw_nd_to_dentry(nd) (nd).dentry
-#endif
-
-/* In 2.6.25-rc2, path_release(&nd) was replaced with path_put(&nd.path). */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
-#define compat_path_release(nd) path_put(&(nd)->path)
-#else
-#define compat_path_release(nd) path_release(nd)
-#endif
-
-/* path_lookup was exported in 2.4.25 */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
-#define compat_path_lookup(path, flags, nd) path_lookup(path, flags, nd)
-#else
-#define compat_path_lookup(path, flags, nd) \
- ({ \
- int ret = 0; \
- if (path_init(path, flags, nd)) { \
- ret = path_walk(path, nd); \
- } \
- ret; \
- })
-#endif
-
-#endif /* __COMPAT_NAMEI_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SEMAPHORE_H__
-# define __COMPAT_SEMAPHORE_H__
-
-
-/* <= 2.6.25 have asm only, 2.6.26 has both, and 2.6.27-rc2+ has linux only. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-# include <asm/semaphore.h>
-#else
-# include <linux/semaphore.h>
-#endif
-
-
-/*
-* The init_MUTEX_LOCKED() API appeared in 2.2.18, and is also in
-* 2.2.17-21mdk --hpreg
-*/
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
- #ifndef init_MUTEX_LOCKED
- #define init_MUTEX_LOCKED(_sem) *(_sem) = MUTEX_LOCKED
- #endif
- #ifndef DECLARE_MUTEX
- #define DECLARE_MUTEX(name) struct semaphore name = MUTEX
- #endif
- #ifndef DECLARE_MUTEX_LOCKED
- #define DECLARE_MUTEX_LOCKED(name) struct semaphore name = MUTEX_LOCKED
- #endif
-#endif
-
-
-#endif /* __COMPAT_SEMAPHORE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SLAB_H__
-# define __COMPAT_SLAB_H__
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# include <linux/slab.h>
-#else
-# include <linux/malloc.h>
-#endif
-
-/*
- * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache
- * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and
- * afterwards it was renamed to kmem_cache. Here we keep things simple and use
- * the accepted typedef until it became deprecated, at which point we switch
- * over to the kmem_cache name.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-# define compat_kmem_cache struct kmem_cache
-#else
-# define compat_kmem_cache kmem_cache_t
-#endif
-
-/*
- * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags,
- * constructor, and destructor. Then for some time kernel was asserting that
- * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5
- * arguments - destructor is gone.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR)
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor, NULL)
-#else
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor)
-#endif
-
-/*
- * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to
- * prepare (aka "this"), from which cache it came, and some unused flags. After
- * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped...
- * Since 2.6.27-rc2 everything is different again, and ctor has only one argument.
- *
- * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_3_ARGS
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_2_ARGS
-#endif
-
-#if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \
- compat_kmem_cache *cache, \
- unsigned long flags
-#elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \
- void *arg
-#else
-typedef void compat_kmem_cache_ctor(void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg
-#endif
-
-#endif /* __COMPAT_SLAB_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * includeCheck.h --
- *
- * Restrict include file use.
- *
- * In every .h file, define one or more of these
- *
- * INCLUDE_ALLOW_VMX
- * INCLUDE_ALLOW_USERLEVEL
- * INCLUDE_ALLOW_VMMEXT
- * INCLUDE_ALLOW_VMCORE
- * INCLUDE_ALLOW_MODULE
- * INCLUDE_ALLOW_VMNIXMOD
- * INCLUDE_ALLOW_VMKERNEL
- * INCLUDE_ALLOW_DISTRIBUTE
- * INCLUDE_ALLOW_VMK_MODULE
- * INCLUDE_ALLOW_VMKDRIVERS
- * INCLUDE_ALLOW_VMIROM
- *
- * Then include this file.
- *
- * Any file that has INCLUDE_ALLOW_DISTRIBUTE defined will potentially
- * be distributed in source form along with GPLed code. Ensure
- * that this is acceptable.
- */
-
-
-/*
- * Declare a VMCORE-only variable to help classify object
- * files. The variable goes in the common block and does
- * not create multiple definition link-time conflicts.
- */
-
-#if defined VMCORE && defined VMX86_DEVEL && defined VMX86_DEBUG && \
- defined linux && !defined MODULE && \
- !defined COMPILED_WITH_VMCORE
-#define COMPILED_WITH_VMCORE compiled_with_vmcore
-#ifdef ASM
- .comm compiled_with_vmcore, 0
-#else
- asm(".comm compiled_with_vmcore, 0");
-#endif /* ASM */
-#endif
-
-
-#if defined VMCORE && \
- !(defined VMX86_VMX || defined VMM || \
- defined MONITOR_APP || defined VMMON)
-#error "Makefile problem: VMCORE without VMX86_VMX or \
- VMM or MONITOR_APP or MODULE."
-#endif
-
-#if defined VMCORE && !defined INCLUDE_ALLOW_VMCORE
-#error "The surrounding include file is not allowed in vmcore."
-#endif
-#undef INCLUDE_ALLOW_VMCORE
-
-#if defined VMX86_VMX && !defined VMCORE && \
- !(defined INCLUDE_ALLOW_VMX || defined INCLUDE_ALLOW_USERLEVEL)
-#error "The surrounding include file is not allowed in the VMX."
-#endif
-#undef INCLUDE_ALLOW_VMX
-
-#if defined USERLEVEL && !defined VMX86_VMX && !defined VMCORE && \
- !defined INCLUDE_ALLOW_USERLEVEL
-#error "The surrounding include file is not allowed at userlevel."
-#endif
-#undef INCLUDE_ALLOW_USERLEVEL
-
-#if defined VMM && !defined VMCORE && \
- !defined INCLUDE_ALLOW_VMMEXT
-#error "The surrounding include file is not allowed in the monitor."
-#endif
-#undef INCLUDE_ALLOW_VMMEXT
-
-#if defined MODULE && !defined VMKERNEL_MODULE && !defined VMNIXMOD && \
- !defined VMMON && !defined INCLUDE_ALLOW_MODULE
-#error "The surrounding include file is not allowed in driver modules."
-#endif
-#undef INCLUDE_ALLOW_MODULE
-
-#if defined VMMON && !defined INCLUDE_ALLOW_VMMON
-#error "The surrounding include file is not allowed in vmmon."
-#endif
-#undef INCLUDE_ALLOW_VMMON
-
-#if defined VMKERNEL && !defined INCLUDE_ALLOW_VMKERNEL
-#error "The surrounding include file is not allowed in the vmkernel."
-#endif
-#undef INCLUDE_ALLOW_VMKERNEL
-
-#if defined GPLED_CODE && !defined INCLUDE_ALLOW_DISTRIBUTE
-#error "The surrounding include file is not allowed in GPL code."
-#endif
-#undef INCLUDE_ALLOW_DISTRIBUTE
-
-#if defined VMKERNEL_MODULE && !defined VMKERNEL && \
- !defined INCLUDE_ALLOW_VMK_MODULE && !defined INCLUDE_ALLOW_VMKDRIVERS
-#error "The surrounding include file is not allowed in vmkernel modules."
-#endif
-#undef INCLUDE_ALLOW_VMK_MODULE
-#undef INCLUDE_ALLOW_VMKDRIVERS
-
-#if defined VMNIXMOD && !defined INCLUDE_ALLOW_VMNIXMOD
-#ifndef VMNIXMOD_VM
-#error "The surrounding include file is not allowed in vmnixmod."
-#endif
-#endif
-#undef INCLUDE_ALLOW_VMNIXMOD
-
-#if defined VMIROM && ! defined INCLUDE_ALLOW_VMIROM
-#error "The surrounding include file is not allowed in vmirom."
-#endif
-#undef INCLUDE_ALLOW_VMIROM
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * syncDriverIoc.h --
- *
- * ioctl commands used by the sync driver on Unix systems.
- *
- * SYNC_IOC_FREEZE: Freezes the provided paths.
- * SYNC_IOC_THAW: Thaws frozen block devices after a FREEZE ioctl.
- * SYNC_IOC_QUERY: Returns the total number of frozen devices (not
- * specific to the fd used).
- */
-
-#ifndef _SYNCDRIVERIOC_H_
-#define _SYNCDRIVERIOC_H_
-
-#ifdef linux
-
-# include <linux/ioctl.h>
-
-# define SYNC_IOC_FREEZE _IOW(0xF5,0x01,const char *)
-# define SYNC_IOC_THAW _IO(0xF5,0x02)
-# define SYNC_IOC_QUERY _IOR(0xF5,0x03,int)
-
-#else
-
-# error "Driver not yet implemented for this OS."
-
-#endif
-
-#endif /* _SYNCDRIVERIOC_H_ */
-
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmxnet
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#### VMware vmxnet Makefile to be distributed externally
####
-INCLUDE := -I.
+INCLUDE += -I.
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
obj-m += $(DRIVER).o
CC_OPTS := -g3 -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS)
-INCLUDE := -I$(HEADER_DIR)
+INCLUDE += -I$(HEADER_DIR)
INCLUDE += $(shell $(CC) $(CC_OPTS) $(INCLUDE) \
- -E $(SRCROOT)/autoconf/geninclude.c \
+ -E $(AUTOCONF_DIR)/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
OBJS := vmxnet.o
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-
-#ifdef CONFIG_X86_VOYAGER
-APATH/mach-voyager
-#endif
-#ifdef CONFIG_X86_VISWS
-APATH/mach-visws
-#endif
-#ifdef CONFIG_X86_NUMAQ
-APATH/mach-numaq
-#endif
-#ifdef CONFIG_X86_BIGSMP
-APATH/mach-bigsmp
-#endif
-#ifdef CONFIG_X86_SUMMIT
-APATH/mach-summit
-#endif
-#ifdef CONFIG_X86_GENERICARCH
-APATH/mach-generic
-#endif
-APATH/mach-default
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_HIGHMEM_H__
-# define __COMPAT_HIGHMEM_H__
-
-
-/*
- * BIGMEM (4 GB) support appeared in 2.3.16: kmap() API added
- * HIGHMEM (4 GB + 64 GB) support appeared in 2.3.23: kmap() API modified
- * In 2.3.27, kmap() API modified again
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 27)
-# include <linux/highmem.h>
-#else
-/* For page_address --hpreg */
-# include <linux/pagemap.h>
-
-# define kmap(_page) (void*)page_address(_page)
-# define kunmap(_page)
-#endif
-
-#endif /* __COMPAT_HIGHMEM_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_init.h: Initialization compatibility wrappers.
- */
-
-#ifndef __COMPAT_INIT_H__
-#define __COMPAT_INIT_H__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-#include <linux/init.h>
-#endif
-
-#ifndef module_init
-#define module_init(x) int init_module(void) { return x(); }
-#endif
-
-#ifndef module_exit
-#define module_exit(x) void cleanup_module(void) { x(); }
-#endif
-
-#endif /* __COMPAT_INIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_INTERRUPT_H__
-# define __COMPAT_INTERRUPT_H__
-
-
-#include <linux/interrupt.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69)
-/*
- * We cannot just define irqreturn_t, as some 2.4.x kernels have
- * typedef void irqreturn_t; for "increasing" backward compatibility.
- */
-typedef void compat_irqreturn_t;
-#define COMPAT_IRQ_NONE
-#define COMPAT_IRQ_HANDLED
-#define COMPAT_IRQ_RETVAL(x)
-#else
-typedef irqreturn_t compat_irqreturn_t;
-#define COMPAT_IRQ_NONE IRQ_NONE
-#define COMPAT_IRQ_HANDLED IRQ_HANDLED
-#define COMPAT_IRQ_RETVAL(x) IRQ_RETVAL(x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
-#define COMPAT_IRQF_DISABLED SA_INTERRUPT
-#define COMPAT_IRQF_SHARED SA_SHIRQ
-#else
-#define COMPAT_IRQF_DISABLED IRQF_DISABLED
-#define COMPAT_IRQF_SHARED IRQF_SHARED
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
-#define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp, struct pt_regs *regs)
-#else
-#define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp)
-#endif
-
-#endif /* __COMPAT_INTERRUPT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_IOPORT_H__
-# define __COMPAT_IOPORT_H__
-
-
-#include <linux/ioport.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-static inline void *
-compat_request_region(unsigned long start, unsigned long len, const char *name)
-{
- if (check_region(start, len)) {
- return NULL;
- }
- request_region(start, len, name);
- return (void*)1;
-}
-#else
-#define compat_request_region(start, len, name) request_region(start, len, name)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 7)
-/* mmap io support starts from 2.3.7, fail the call for kernel prior to that */
-static inline void *
-compat_request_mem_region(unsigned long start, unsigned long len, const char *name)
-{
- return NULL;
-}
-
-static inline void
-compat_release_mem_region(unsigned long start, unsigned long len)
-{
- return;
-}
-#else
-#define compat_request_mem_region(start, len, name) request_mem_region(start, len, name)
-#define compat_release_mem_region(start, len) release_mem_region(start, len)
-#endif
-
-/* these two macro defs are needed by compat_pci_request_region */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15)
-# define IORESOURCE_IO 0x00000100
-# define IORESOURCE_MEM 0x00000200
-#endif
-
-#endif /* __COMPAT_IOPORT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_NETDEVICE_H__
-# define __COMPAT_NETDEVICE_H__
-
-
-#include <linux/skbuff.h>
-#include <linux/rtnetlink.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-/*
- * The enet_statistics structure moved from linux/if_ether.h to
- * linux/netdevice.h and is renamed net_device_stats in 2.1.25 --hpreg
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 25)
-# include <linux/if_ether.h>
-
-# define net_device_stats enet_statistics
-#endif
-
-
-/* The netif_rx_ni() API appeared in 2.4.8 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 8)
-# define netif_rx_ni netif_rx
-#endif
-
-
-/* The device struct was renamed net_device in 2.3.14 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)
-# define net_device device
-#endif
-
-
-/*
- * SET_MODULE_OWNER appeared sometime during 2.3.x. It was setting
- * dev->owner = THIS_MODULE until 2.5.70, where netdevice refcounting
- * was completely changed. SET_MODULE_OWNER was nop for whole
- * 2.6.x series, and finally disappeared in 2.6.24.
- *
- * MOD_xxx_USE_COUNT wrappers are here, as they must be mutually
- * exclusive with SET_MODULE_OWNER call.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-# define COMPAT_SET_MODULE_OWNER(dev) do {} while (0)
-# define COMPAT_NETDEV_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
-# define COMPAT_NETDEV_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
-#else
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-# define COMPAT_SET_MODULE_OWNER(dev) SET_MODULE_OWNER(dev)
-# else
-# define COMPAT_SET_MODULE_OWNER(dev) do {} while (0)
-# endif
-# define COMPAT_NETDEV_MOD_INC_USE_COUNT do {} while (0)
-# define COMPAT_NETDEV_MOD_DEC_USE_COUNT do {} while (0)
-#endif
-
-/*
- * SET_NETDEV_DEV appeared sometime during 2.5.x, and later was
- * crossported to various 2.4.x kernels (as dummy macro).
- */
-#ifdef SET_NETDEV_DEV
-# define COMPAT_SET_NETDEV_DEV(dev, pdev) SET_NETDEV_DEV(dev, pdev)
-#else
-# define COMPAT_SET_NETDEV_DEV(dev, pdev) do {} while (0)
-#endif
-
-/*
- * Build alloc_etherdev API on the top of init_etherdev. For 2.0.x kernels
- * we must provide dummy init method, otherwise register_netdev does
- * nothing.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-int
-vmware_dummy_init(struct net_device *dev)
-{
- return 0;
-}
-#endif
-
-
-static inline struct net_device*
-compat_alloc_etherdev(int priv_size)
-{
- struct net_device* dev;
- int size = sizeof *dev + priv_size;
-
- /*
- * The name is dynamically allocated before 2.4.0, but
- * is an embedded array in later kernels.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
- size += sizeof("ethXXXXXXX");
-#endif
- dev = kmalloc(size, GFP_KERNEL);
- if (dev) {
- memset(dev, 0, size);
- if (priv_size) {
- dev->priv = dev + 1;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
- dev->name = (char *)(dev + 1) + priv_size;
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
- dev->init = vmware_dummy_init;
-#endif
- if (init_etherdev(dev, 0) != dev) {
- kfree(dev);
- dev = NULL;
- }
- }
- return dev;
-}
-#else
-#define compat_alloc_etherdev(sz) alloc_etherdev(sz)
-#endif
-
-
-/*
- * alloc_netdev and free_netdev are there since 2.4.23. Their use is mandatory
- * since 2.6.24.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
-static inline struct net_device *
-compat_alloc_netdev(int priv_size,
- const char *mask,
- void (*setup)(struct net_device *))
-{
- struct net_device *dev;
- int netdev_size = sizeof *dev;
- int alloc_size;
-
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
- netdev_size += IFNAMSIZ;
-# endif
-
- alloc_size = netdev_size + priv_size;
- dev = kmalloc(alloc_size, GFP_KERNEL);
- if (dev) {
- memset(dev, 0, alloc_size);
- dev->priv = (char*)dev + netdev_size;
- setup(dev);
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
- dev->name = (char*)(dev + 1);
-# endif
- strcpy(dev->name, mask);
- }
- return dev;
-}
-# define compat_free_netdev(dev) kfree(dev)
-#else
-# define compat_alloc_netdev(size, mask, setup) alloc_netdev(size, mask, setup)
-# define compat_free_netdev(dev) free_netdev(dev)
-#endif
-
-/* netdev_priv() appeared in 2.6.3 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 3)
-# define compat_netdev_priv(netdev) (netdev)->priv
-#else
-# define compat_netdev_priv(netdev) netdev_priv(netdev)
-#endif
-
-/*
- * All compat_* business is good but when we can we should just provide
- * missing implementation to ease upstreaming task.
- */
-#ifndef HAVE_ALLOC_NETDEV
-#define alloc_netdev(sz, name, setup) compat_alloc_netdev(sz, name, setup)
-#define alloc_etherdev(sz) compat_alloc_etherdev(sz)
-#endif
-
-#ifndef HAVE_FREE_NETDEV
-#define free_netdev(dev) kfree(dev)
-#endif
-
-#ifndef HAVE_NETDEV_PRIV
-#define netdev_priv(dev) ((dev)->priv)
-#endif
-
-#if defined(NETDEV_TX_OK)
-# define COMPAT_NETDEV_TX_OK NETDEV_TX_OK
-# define COMPAT_NETDEV_TX_BUSY NETDEV_TX_BUSY
-#else
-# define COMPAT_NETDEV_TX_OK 0
-# define COMPAT_NETDEV_TX_BUSY 1
-#endif
-
-#ifndef HAVE_NETIF_QUEUE
-static inline void
-netif_start_queue(struct device *dev)
-{
- clear_bit(0, &dev->tbusy);
-}
-
-static inline void
-netif_stop_queue(struct device *dev)
-{
- set_bit(0, &dev->tbusy);
-}
-
-static inline int
-netif_queue_stopped(struct device *dev)
-{
- return test_bit(0, &dev->tbusy);
-}
-
-static inline void
-netif_wake_queue(struct device *dev)
-{
- clear_bit(0, &dev->tbusy);
- mark_bh(NET_BH);
-}
-
-static inline int
-netif_running(struct device *dev)
-{
- return dev->start == 0;
-}
-
-static inline int
-netif_carrier_ok(struct device *dev)
-{
- return 1;
-}
-
-static inline void
-netif_carrier_on(struct device *dev)
-{
-}
-
-static inline void
-netif_carrier_off(struct device *dev)
-{
-}
-#endif
-
-/* Keep compat_* defines for now */
-#define compat_netif_start_queue(dev) netif_start_queue(dev)
-#define compat_netif_stop_queue(dev) netif_stop_queue(dev)
-#define compat_netif_queue_stopped(dev) netif_queue_stopped(dev)
-#define compat_netif_wake_queue(dev) netif_wake_queue(dev)
-#define compat_netif_running(dev) netif_running(dev)
-#define compat_netif_carrier_ok(dev) netif_carrier_ok(dev)
-#define compat_netif_carrier_on(dev) netif_carrier_on(dev)
-#define compat_netif_carrier_off(dev) netif_carrier_off(dev)
-
-/* unregister_netdevice_notifier was not safe prior to 2.6.17 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) && \
- !defined(ATOMIC_NOTIFIER_INIT)
-/* pre 2.6.17 and not patched */
-static inline int compat_unregister_netdevice_notifier(struct notifier_block *nb) {
- int err;
-
- rtnl_lock();
- err = unregister_netdevice_notifier(nb);
- rtnl_unlock();
- return err;
-}
-#else
-/* post 2.6.17 or patched */
-#define compat_unregister_netdevice_notifier(_nb) \
- unregister_netdevice_notifier(_nb);
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-#define compat_netif_napi_add(dev, napi, poll, quota) \
- netif_napi_add(dev, napi, poll, quota)
-
-#ifdef VMW_NETIF_SINGLE_NAPI_PARM
-#define compat_netif_rx_complete(dev, napi) netif_rx_complete(napi)
-#define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(napi)
-#else
-#define compat_netif_rx_complete(dev, napi) netif_rx_complete(dev, napi)
-#define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(dev, napi)
-#endif
-
-#define compat_napi_enable(dev, napi) napi_enable(napi)
-#define compat_napi_disable(dev, napi) napi_disable(napi)
-#else
-struct napi_struct {
- int dummy;
-};
-
-#define compat_netif_napi_add(dev, napi, pollcb, quota) \
- do { \
- (dev)->poll = (pollcb); \
- (dev)->weight = (quota);\
- } while (0)
-#define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(dev)
-#define compat_napi_enable(dev, napi) netif_poll_enable(dev)
-#define compat_napi_disable(dev, napi) netif_poll_disable(dev)
-#endif
-
-#endif /* __COMPAT_NETDEVICE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_pci.h: PCI compatibility wrappers.
- */
-
-#ifndef __COMPAT_PCI_H__
-#define __COMPAT_PCI_H__
-
-#include "compat_ioport.h"
-#include <linux/pci.h>
-#ifndef KERNEL_2_1
-# include <linux/bios32.h>
-#endif
-
-
-/* 2.0.x has useless struct pci_dev; remap it to our own */
-#ifndef KERNEL_2_1
-#define pci_dev vmw_pci_driver_instance
-#endif
-
-
-/* 2.0/2.2 does not have pci driver API */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-struct vmw_pci_driver_instance {
- struct vmw_pci_driver_instance *next;
- void *driver_data;
- struct pci_driver *pcidrv;
-#ifdef KERNEL_2_1
- struct pci_dev *pcidev;
-#else
- unsigned char bus;
- unsigned char devfn;
- unsigned int irq;
-#endif
-};
-#endif
-
-
-/* 2.0 has pcibios_* calls only... We have to provide pci_* compatible wrappers. */
-#ifndef KERNEL_2_1
-static inline int
-pci_read_config_byte(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Byte to read
- u8 *value) // OUT: Value read
-{
- return pcibios_read_config_byte(pdev->bus, pdev->devfn, where, value);
-}
-
-static inline int
-pci_read_config_dword(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Dword to read
- u32 *value) // OUT: Value read
-{
- return pcibios_read_config_dword(pdev->bus, pdev->devfn, where, value);
-}
-
-static inline int
-pci_write_config_dword(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Dword to write
- u32 value) // IN: Value to write
-{
- return pcibios_write_config_dword(pdev->bus, pdev->devfn, where, value);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * compat_pci_name --
- *
- * Return human readable PCI slot name. Note that some implementations
- * return a pointer to the static storage, so returned value may be
- * overwritten by subsequent calls to this function.
- *
- * Results:
- * Returns pointer to the string with slot name.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-#define compat_pci_name(pdev) pci_name(pdev)
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-#define compat_pci_name(pdev) (pdev)->slot_name
-#elif defined(KERNEL_2_1)
-static inline const char*
-compat_pci_name(struct pci_dev* pdev)
-{
- static char slot_name[12];
- sprintf(slot_name, "%02X:%02X.%X", pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
- return slot_name;
-}
-#else
-static inline const char*
-compat_pci_name(struct pci_dev* pdev)
-{
- static char slot_name[12];
- sprintf(slot_name, "%02X:%02X.%X", pdev->bus,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
- return slot_name;
-}
-#endif
-
-
-/* pci_resource_start comes in 4 flavors - 2.0, 2.2, early 2.3, 2.4+ */
-#ifndef KERNEL_2_1
-static inline unsigned long
-compat_pci_resource_start(struct pci_dev *pdev,
- unsigned int index)
-{
- u32 addr;
-
- if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
- printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
- index, compat_pci_name(pdev));
- return ~0UL;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return addr & PCI_BASE_ADDRESS_IO_MASK;
- } else {
- return addr & PCI_BASE_ADDRESS_MEM_MASK;
- }
-}
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
-# define compat_pci_resource_start(dev, index) \
- (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
- ? ((dev)->base_address[index] & PCI_BASE_ADDRESS_IO_MASK) \
- : ((dev)->base_address[index] & PCI_BASE_ADDRESS_MEM_MASK))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)
-# define compat_pci_resource_start(dev, index) \
- ((dev)->resource[index].start)
-#else
-# define compat_pci_resource_start(dev, index) \
- pci_resource_start(dev, index)
-#endif
-
-/* since 2.3.15, a new set of s/w res flags IORESOURCE_ is introduced,
- * we fake them by returning either IORESOURCE_{IO, MEM} prior to 2.3.15 since
- * this is what compat_pci_request_region uses
- */
-#ifndef KERNEL_2_1
-static inline unsigned long
-compat_pci_resource_flags(struct pci_dev *pdev,
- unsigned int index)
-{
- u32 addr;
-
- if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
- printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
- index, compat_pci_name(pdev));
- return ~0UL;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return IORESOURCE_IO;
- } else {
- return IORESOURCE_MEM;
- }
-}
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
-# define compat_pci_resource_flags(dev, index) \
- (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
- ? IORESOURCE_IO: IORESOURCE_MEM)
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15)
- /* IORESOURCE_xxx appeared in 2.3.15 and is set in resource[].flags */
-# define compat_pci_resource_flags(dev, index) ((dev)->resource[index].flags)
-#else
-# define compat_pci_resource_flags(dev, index) pci_resource_flags(dev, index)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
-static inline unsigned long
-compat_pci_resource_len(struct pci_dev *pdev, // IN
- unsigned int index) // IN
-{
- u32 addr, mask;
- unsigned char reg = PCI_BASE_ADDRESS_0 + index * 4;
-
- if (pci_read_config_dword(pdev, reg, &addr) || addr == 0xFFFFFFFF) {
- return 0;
- }
-
- pci_write_config_dword(pdev, reg, 0xFFFFFFFF);
- pci_read_config_dword(pdev, reg, &mask);
- pci_write_config_dword(pdev, reg, addr);
-
- if (mask == 0 || mask == 0xFFFFFFFF) {
- return 0;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return 65536 - (mask & PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
- } else {
- return -(mask & PCI_BASE_ADDRESS_MEM_MASK);
- }
-}
-#else
-#define compat_pci_resource_len(dev, index) pci_resource_len(dev, index)
-#endif
-
-/* pci_request_region appears in 2.4.20 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
-static inline int
-compat_pci_request_region(struct pci_dev *pdev, int bar, char *name)
-{
- if (compat_pci_resource_len(pdev, bar) == 0) {
- return 0;
- }
-
- if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
- if (!compat_request_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar),
- name)) {
- return -EBUSY;
- }
- } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
- if (!compat_request_mem_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar),
- name)) {
- return -EBUSY;
- }
- }
-
- return 0;
-}
-
-static inline void
-compat_pci_release_region(struct pci_dev *pdev, int bar)
-{
- if (compat_pci_resource_len(pdev, bar) != 0) {
- if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
- release_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar));
- } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
- compat_release_mem_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar));
- }
- }
-}
-#else
-#define compat_pci_request_region(pdev, bar, name) pci_request_region(pdev, bar, name)
-#define compat_pci_release_region(pdev, bar) pci_release_region(pdev, bar)
-#endif
-
-/* pci_request_regions appeears in 2.4.3 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)
-static inline int
-compat_pci_request_regions(struct pci_dev *pdev, char *name)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- if (compat_pci_request_region(pdev, i, name)) {
- goto release;
- }
- }
- return 0;
-
-release:
- while (--i >= 0) {
- compat_pci_release_region(pdev, i);
- }
- return -EBUSY;
-}
-static inline void
-compat_pci_release_regions(struct pci_dev *pdev)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- compat_pci_release_region(pdev, i);
- }
-}
-#else
-#define compat_pci_request_regions(pdev, name) pci_request_regions(pdev, name)
-#define compat_pci_release_regions(pdev) pci_release_regions(pdev)
-#endif
-
-/* pci_enable_device is available since 2.4.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define compat_pci_enable_device(pdev) (0)
-#else
-#define compat_pci_enable_device(pdev) pci_enable_device(pdev)
-#endif
-
-
-/* pci_set_master is available since 2.2.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-#define compat_pci_set_master(pdev) (0)
-#else
-#define compat_pci_set_master(pdev) pci_set_master(pdev)
-#endif
-
-
-/* pci_disable_device is available since 2.4.4 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 4)
-#define compat_pci_disable_device(pdev) do {} while (0)
-#else
-#define compat_pci_disable_device(pdev) pci_disable_device(pdev)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-/*
- * Devices supported by particular pci driver. While 2.4+ kernels
- * can do match on subsystem and class too, we support match on
- * vendor/device IDs only.
- */
-struct pci_device_id {
- unsigned int vendor, device;
- unsigned long driver_data;
-};
-#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev)
-
-/* PCI driver */
-struct pci_driver {
- const char *name;
- const struct pci_device_id *id_table;
- int (*probe)(struct pci_dev* dev, const struct pci_device_id* id);
- void (*remove)(struct pci_dev* dev);
-};
-
-
-/*
- * Note that this is static variable. Maybe everything below should be in
- * separate compat_pci.c file, but currently only user of this file is vmxnet,
- * and vmxnet has only one file, so it is fine. Also with vmxnet all
- * functions below are called just once, so difference between 'inline' and
- * separate compat_pci.c should be very small.
- */
-
-static struct vmw_pci_driver_instance *pci_driver_instances = NULL;
-
-#ifdef KERNEL_2_1
-#define vmw_pci_device(instance) (instance)->pcidev
-#else
-#define vmw_pci_device(instance) (instance)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_register_driver --
- *
- * Create driver instances for all matching PCI devices in the box.
- *
- * Results:
- * Returns 0 for success, negative error value for failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static inline int
-pci_register_driver(struct pci_driver *drv)
-{
- const struct pci_device_id *chipID;
-
- for (chipID = drv->id_table; chipID->vendor; chipID++) {
-#ifdef KERNEL_2_1
- struct pci_dev *pdev;
-
- for (pdev = NULL;
- (pdev = pci_find_device(chipID->vendor, chipID->device, pdev)) != NULL; ) {
-#else
- int adapter;
- unsigned char bus, devfn, irq;
-
- for (adapter = 0;
- pcibios_find_device(chipID->vendor, chipID->device, adapter,
- &bus, &devfn) == 0;
- adapter++) {
-#endif
- struct vmw_pci_driver_instance *pdi;
- int err;
-
- pdi = kmalloc(sizeof *pdi, GFP_KERNEL);
- if (!pdi) {
- printk(KERN_ERR "Not enough memory.\n");
- break;
- }
- pdi->pcidrv = drv;
-#ifdef KERNEL_2_1
- pdi->pcidev = pdev;
-#else
- pdi->bus = bus;
- pdi->devfn = devfn;
- if (pci_read_config_byte(pdi, PCI_INTERRUPT_LINE, &irq)) {
- pdi->irq = -1;
- } else {
- pdi->irq = irq;
- }
-#endif
- pdi->driver_data = NULL;
- pdi->next = pci_driver_instances;
- pci_driver_instances = pdi;
- err = drv->probe(vmw_pci_device(pdi), chipID);
- if (err) {
- pci_driver_instances = pdi->next;
- kfree(pdi);
- }
- }
- }
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * compat_pci_unregister_driver --
- *
- * Shut down PCI driver - unbind all device instances from driver.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static inline void
-pci_unregister_driver(struct pci_driver *drv)
-{
- struct vmw_pci_driver_instance **ppdi;
-
- ppdi = &pci_driver_instances;
- while (1) {
- struct vmw_pci_driver_instance *pdi = *ppdi;
-
- if (!pdi) {
- break;
- }
- if (pdi->pcidrv == drv) {
- drv->remove(vmw_pci_device(pdi));
- *ppdi = pdi->next;
- kfree(pdi);
- } else {
- ppdi = &pdi->next;
- }
- }
-}
-#else
-/* provide PCI_DEVICE for early 2.4.x kernels */
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif
-#endif
-
-
-/* provide dummy MODULE_DEVICE_TABLE for 2.0/2.2 */
-#ifndef MODULE_DEVICE_TABLE
-#define MODULE_DEVICE_TABLE(bus, devices)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_set_drvdata --
- *
- * Set per-device driver's private data.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_get_drvdata --
- *
- * Retrieve per-device driver's private data.
- *
- * Results:
- * per-device driver's data previously set by pci_set_drvdata,
- * or NULL on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-#ifndef KERNEL_2_1
-/* 2.0.x is simple, we have driver_data directly in pci_dev */
-#define pci_set_drvdata(pdev, data) do { (pdev)->driver_data = (data); } while (0)
-#define pci_get_drvdata(pdev) (pdev)->driver_data
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-/* 2.2.x is trickier, we have to find driver instance first */
-static inline void
-pci_set_drvdata(struct pci_dev *pdev, void* data)
-{
- struct vmw_pci_driver_instance *pdi;
-
- for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
- if (pdi->pcidev == pdev) {
- pdi->driver_data = data;
- return;
- }
- }
- printk(KERN_ERR "pci_set_drvdata issued for unknown device %p\n", pdev);
-}
-
-static inline void *
-pci_get_drvdata(struct pci_dev *pdev)
-{
- struct vmw_pci_driver_instance *pdi;
-
- for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
- if (pdi->pcidev == pdev) {
- return pdi->driver_data;
- }
- }
- printk(KERN_ERR "pci_get_drvdata issued for unknown device %p\n", pdev);
- return NULL;
-}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)
-# define PCI_DMA_BIDIRECTIONAL 0
-# define PCI_DMA_TODEVICE 1
-# define PCI_DMA_FROMDEVICE 2
-# define PCI_DMA_NONE 3
-#endif
-
-/*
- * Power Management related compat wrappers.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
-# define compat_pci_save_state(pdev) pci_save_state((pdev), NULL)
-# define compat_pci_restore_state(pdev) pci_restore_state((pdev), NULL)
-#else
-# define compat_pci_save_state(pdev) pci_save_state((pdev))
-# define compat_pci_restore_state(pdev) pci_restore_state((pdev))
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
-# define pm_message_t u32
-# define compat_pci_choose_state(pdev, state) (state)
-# define PCI_D0 0
-# define PCI_D3hot 3
-#else
-# define compat_pci_choose_state(pdev, state) pci_choose_state((pdev), (state))
-#endif
-
-/* 2.6.14 changed the PCI shutdown callback */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
-# define COMPAT_PCI_SHUTDOWN(func) .driver = { .shutdown = (func), }
-# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct device *(var))
-# define COMPAT_PCI_TO_DEV(dev) (to_pci_dev(dev))
-#else
-# define COMPAT_PCI_SHUTDOWN(func) .shutdown = (func)
-# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct pci_dev *(var))
-# define COMPAT_PCI_TO_DEV(dev) (dev)
-#endif
-
-
-#endif /* __COMPAT_PCI_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SLAB_H__
-# define __COMPAT_SLAB_H__
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# include <linux/slab.h>
-#else
-# include <linux/malloc.h>
-#endif
-
-/*
- * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache
- * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and
- * afterwards it was renamed to kmem_cache. Here we keep things simple and use
- * the accepted typedef until it became deprecated, at which point we switch
- * over to the kmem_cache name.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-# define compat_kmem_cache struct kmem_cache
-#else
-# define compat_kmem_cache kmem_cache_t
-#endif
-
-/*
- * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags,
- * constructor, and destructor. Then for some time kernel was asserting that
- * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5
- * arguments - destructor is gone.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR)
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor, NULL)
-#else
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor)
-#endif
-
-/*
- * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to
- * prepare (aka "this"), from which cache it came, and some unused flags. After
- * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped...
- * Since 2.6.27-rc2 everything is different again, and ctor has only one argument.
- *
- * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_3_ARGS
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_2_ARGS
-#endif
-
-#if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \
- compat_kmem_cache *cache, \
- unsigned long flags
-#elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \
- void *arg
-#else
-typedef void compat_kmem_cache_ctor(void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg
-#endif
-
-#endif /* __COMPAT_SLAB_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SPINLOCK_H__
-# define __COMPAT_SPINLOCK_H__
-
-
-/*
- * The spin_lock() API appeared in 2.1.25 in asm/smp_lock.h
- * It moved in 2.1.30 to asm/spinlock.h
- * It moved again in 2.3.18 to linux/spinlock.h
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 18)
-# include <linux/spinlock.h>
-#else
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30)
-# include <asm/spinlock.h>
-# else
-typedef struct {} spinlock_t;
-# define spin_lock_init(lock)
-# define spin_lock(lock)
-# define spin_unlock(lock)
-# define spin_lock_irqsave(lock, flags) do { \
- save_flags(flags); \
- cli(); \
- spin_lock(lock); \
- } while (0)
-# define spin_unlock_irqrestore(lock, flags) do { \
- spin_unlock(lock); \
- restore_flags(flags); \
- } while (0)
-# endif
-#endif
-
-
-/*
- * Preempt support was added during 2.5.x development cycle, and later
- * it was backported to 2.4.x. In 2.4.x backport these definitions
- * live in linux/spinlock.h, that's why we put them here (in 2.6.x they
- * are defined in linux/preempt.h which is included by linux/spinlock.h).
- */
-#ifdef CONFIG_PREEMPT
-#define compat_preempt_disable() preempt_disable()
-#define compat_preempt_enable() preempt_enable()
-#else
-#define compat_preempt_disable() do { } while (0)
-#define compat_preempt_enable() do { } while (0)
-#endif
-
-
-#endif /* __COMPAT_SPINLOCK_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * includeCheck.h --
- *
- * Restrict include file use.
- *
- * In every .h file, define one or more of these
- *
- * INCLUDE_ALLOW_VMX
- * INCLUDE_ALLOW_USERLEVEL
- * INCLUDE_ALLOW_VMMEXT
- * INCLUDE_ALLOW_VMCORE
- * INCLUDE_ALLOW_MODULE
- * INCLUDE_ALLOW_VMNIXMOD
- * INCLUDE_ALLOW_VMKERNEL
- * INCLUDE_ALLOW_DISTRIBUTE
- * INCLUDE_ALLOW_VMK_MODULE
- * INCLUDE_ALLOW_VMKDRIVERS
- * INCLUDE_ALLOW_VMIROM
- *
- * Then include this file.
- *
- * Any file that has INCLUDE_ALLOW_DISTRIBUTE defined will potentially
- * be distributed in source form along with GPLed code. Ensure
- * that this is acceptable.
- */
-
-
-/*
- * Declare a VMCORE-only variable to help classify object
- * files. The variable goes in the common block and does
- * not create multiple definition link-time conflicts.
- */
-
-#if defined VMCORE && defined VMX86_DEVEL && defined VMX86_DEBUG && \
- defined linux && !defined MODULE && \
- !defined COMPILED_WITH_VMCORE
-#define COMPILED_WITH_VMCORE compiled_with_vmcore
-#ifdef ASM
- .comm compiled_with_vmcore, 0
-#else
- asm(".comm compiled_with_vmcore, 0");
-#endif /* ASM */
-#endif
-
-
-#if defined VMCORE && \
- !(defined VMX86_VMX || defined VMM || \
- defined MONITOR_APP || defined VMMON)
-#error "Makefile problem: VMCORE without VMX86_VMX or \
- VMM or MONITOR_APP or MODULE."
-#endif
-
-#if defined VMCORE && !defined INCLUDE_ALLOW_VMCORE
-#error "The surrounding include file is not allowed in vmcore."
-#endif
-#undef INCLUDE_ALLOW_VMCORE
-
-#if defined VMX86_VMX && !defined VMCORE && \
- !(defined INCLUDE_ALLOW_VMX || defined INCLUDE_ALLOW_USERLEVEL)
-#error "The surrounding include file is not allowed in the VMX."
-#endif
-#undef INCLUDE_ALLOW_VMX
-
-#if defined USERLEVEL && !defined VMX86_VMX && !defined VMCORE && \
- !defined INCLUDE_ALLOW_USERLEVEL
-#error "The surrounding include file is not allowed at userlevel."
-#endif
-#undef INCLUDE_ALLOW_USERLEVEL
-
-#if defined VMM && !defined VMCORE && \
- !defined INCLUDE_ALLOW_VMMEXT
-#error "The surrounding include file is not allowed in the monitor."
-#endif
-#undef INCLUDE_ALLOW_VMMEXT
-
-#if defined MODULE && !defined VMKERNEL_MODULE && !defined VMNIXMOD && \
- !defined VMMON && !defined INCLUDE_ALLOW_MODULE
-#error "The surrounding include file is not allowed in driver modules."
-#endif
-#undef INCLUDE_ALLOW_MODULE
-
-#if defined VMMON && !defined INCLUDE_ALLOW_VMMON
-#error "The surrounding include file is not allowed in vmmon."
-#endif
-#undef INCLUDE_ALLOW_VMMON
-
-#if defined VMKERNEL && !defined INCLUDE_ALLOW_VMKERNEL
-#error "The surrounding include file is not allowed in the vmkernel."
-#endif
-#undef INCLUDE_ALLOW_VMKERNEL
-
-#if defined GPLED_CODE && !defined INCLUDE_ALLOW_DISTRIBUTE
-#error "The surrounding include file is not allowed in GPL code."
-#endif
-#undef INCLUDE_ALLOW_DISTRIBUTE
-
-#if defined VMKERNEL_MODULE && !defined VMKERNEL && \
- !defined INCLUDE_ALLOW_VMK_MODULE && !defined INCLUDE_ALLOW_VMKDRIVERS
-#error "The surrounding include file is not allowed in vmkernel modules."
-#endif
-#undef INCLUDE_ALLOW_VMK_MODULE
-#undef INCLUDE_ALLOW_VMKDRIVERS
-
-#if defined VMNIXMOD && !defined INCLUDE_ALLOW_VMNIXMOD
-#ifndef VMNIXMOD_VM
-#error "The surrounding include file is not allowed in vmnixmod."
-#endif
-#endif
-#undef INCLUDE_ALLOW_VMNIXMOD
-
-#if defined VMIROM && ! defined INCLUDE_ALLOW_VMIROM
-#error "The surrounding include file is not allowed in vmirom."
-#endif
-#undef INCLUDE_ALLOW_VMIROM
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- *
- * vm_basic_types.h --
- *
- * basic data types.
- */
-
-
-#ifndef _VM_BASIC_TYPES_H_
-#define _VM_BASIC_TYPES_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-/* STRICT ANSI means the Xserver build and X defines Bool differently. */
-#if !defined(__STRICT_ANSI__) || defined(__FreeBSD__)
-typedef char Bool;
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define IsBool(x) (((x) & ~1) == 0)
-#define IsBool2(x, y) ((((x) | (y)) & ~1) == 0)
-
-/*
- * Macros __i386__ and __ia64 are intrinsically defined by GCC
- */
-#ifdef __i386__
-#define VM_I386
-#endif
-
-#ifdef _WIN64
-#define __x86_64__
-#endif
-
-#ifdef __x86_64__
-#define VM_X86_64
-#define VM_I386
-#define vm_x86_64 (1)
-#else
-#define vm_x86_64 (0)
-#endif
-
-
-
-#ifdef _WIN32
-/* safe assumption for a while */
-#define VM_I386
-#endif
-
-#ifdef _MSC_VER
-
-#pragma warning (3 :4505) // unreferenced local function
-#pragma warning (disable :4018) // signed/unsigned mismatch
-#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
-#pragma warning (disable :4305) // truncation from 'const int' to 'short'
-#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
-#pragma warning (disable :4267) // truncation of 'size_t'
-#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
-#pragma warning (disable :4142) // benign redefinition of type
-
-#endif
-
-#if defined(__APPLE__) || defined(HAVE_STDINT_H)
-
-/*
- * TODO: This is a C99 standard header. We should be able to test for
- * #if __STDC_VERSION__ >= 199901L, but that breaks the Netware build
- * (which doesn't have stdint.h).
- */
-
-#include <stdint.h>
-
-typedef uint64_t uint64;
-typedef int64_t int64;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint8_t uint8;
-
-/*
- * XXX: int8_t is defined to be 'signed char' on Mac hosts.
- *
- * Unfortunately, GCC 4.0.1 warns when doing pointer assignment or
- * comparison between signed char * and char * (even if char is
- * signed).
- *
- * If we want to use int8_t to define int8, we need to go through and
- * replace uses of char * with signed char * to prevent warnings.
- */
-typedef char int8;
-
-#else /* !HAVE_STDINT_H */
-
-#ifdef _MSC_VER
-
-typedef unsigned __int64 uint64;
-typedef signed __int64 int64;
-
-#elif __GNUC__
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-#if defined(VM_X86_64)
-typedef unsigned long uint64;
-typedef long int64;
-#else
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#elif __FreeBSD__
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#else
-#error - Need compiler define for int64/uint64
-#endif /* _MSC_VER */
-
-typedef unsigned int uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
-typedef int int32;
-typedef short int16;
-typedef char int8;
-
-#endif /* HAVE_STDINT_H */
-
-/*
- * FreeBSD (for the tools build) unconditionally defines these in
- * sys/inttypes.h so don't redefine them if this file has already
- * been included. [greg]
- *
- * This applies to Solaris as well.
- */
-
-/*
- * Before trying to do the includes based on OS defines, see if we can use
- * feature-based defines to get as much functionality as possible
- */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_INTTYPES_H
-#include <sys/inttypes.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
-#endif
-
-#if !defined(USING_AUTOCONF)
-# if defined(__FreeBSD__) || defined(sun)
-# ifdef KLD_MODULE
-# include <sys/types.h>
-# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
-# include <sys/types.h>
-# else
-# include <sys/inttypes.h>
-# endif
-# endif
-# elif defined __APPLE__
-# if KERNEL
-# include <sys/unistd.h>
-# include <sys/types.h> /* mostly for size_t */
-# include <stdint.h>
-# else
-# include <unistd.h>
-# include <inttypes.h>
-# include <stdlib.h>
-# include <stdint.h>
-# endif
-# else
-# if !defined(__intptr_t_defined) && !defined(intptr_t)
-# define __intptr_t_defined
-# define intptr_t intptr_t
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef int64 intptr_t;
-# else
-typedef int32 intptr_t;
-# endif
-# endif
-# endif
-
-# ifndef _STDINT_H
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef uint64 uintptr_t;
-# else
-typedef uint32 uintptr_t;
-# endif
-# endif
-# endif
-# endif
-#endif
-
-
-/*
- * Time
- * XXX These should be cleaned up. -- edward
- */
-
-typedef int64 VmTimeType; /* Time in microseconds */
-typedef int64 VmTimeRealClock; /* Real clock kept in microseconds */
-typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */
-
-/*
- * Printf format specifiers for size_t and 64-bit number.
- * Use them like this:
- * printf("%"FMT64"d\n", big);
- *
- * FMTH is for handles/fds.
- */
-
-#ifdef _MSC_VER
- #define FMT64 "I64"
- #ifdef VM_X86_64
- #define FMTSZ "I64"
- #define FMTPD "I64"
- #define FMTH "I64"
- #else
- #define FMTSZ "I"
- #define FMTPD "I"
- #define FMTH "I"
- #endif
-#elif defined __APPLE__
- /* Mac OS hosts use the same formatters for 32- and 64-bit. */
- #define FMT64 "ll"
- #define FMTSZ "z"
- #define FMTPD "l"
- #define FMTH ""
-#elif __GNUC__
- #define FMTH ""
- #if defined(N_PLAT_NLM) || defined(sun) || \
- (defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) < 5))
- /*
- * Why (__FreeBSD__ + 0)? See bug 141008.
- * Yes, we really need to test both (__FreeBSD__ + 0) and
- * ((__FreeBSD__ + 0) < 5). No, we can't remove "+ 0" from
- * ((__FreeBSD__ + 0) < 5).
- */
- #ifdef VM_X86_64
- #define FMTSZ "l"
- #define FMTPD "l"
- #else
- #define FMTSZ ""
- #define FMTPD ""
- #endif
- #elif defined(__linux__) \
- || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
- || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
- || (defined(_POSIX2_VERSION) && _POSIX2_VERSION >= 200112L)
- /* BSD, Linux */
- #define FMTSZ "z"
-
- #if defined(VM_X86_64)
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #else
- /* Systems with a pre-C99 libc */
- #define FMTSZ "Z"
- #ifdef VM_X86_64
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #endif
- #ifdef VM_X86_64
- #define FMT64 "l"
- #elif defined(sun) || defined(__FreeBSD__)
- #define FMT64 "ll"
- #else
- #define FMT64 "L"
- #endif
-#else
- #error - Need compiler define for FMT64 and FMTSZ
-#endif
-
-/*
- * Suffix for 64-bit constants. Use it like this:
- * CONST64(0x7fffffffffffffff) for signed or
- * CONST64U(0x7fffffffffffffff) for unsigned.
- *
- * 2004.08.30(thutt):
- * The vmcore/asm64/gen* programs are compiled as 32-bit
- * applications, but must handle 64 bit constants. If the
- * 64-bit-constant defining macros are already defined, the
- * definition will not be overwritten.
- */
-
-#if !defined(CONST64) || !defined(CONST64U)
-#ifdef _MSC_VER
-#define CONST64(c) c##I64
-#define CONST64U(c) c##uI64
-#elif defined __APPLE__
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#elif __GNUC__
-#ifdef VM_X86_64
-#define CONST64(c) c##L
-#define CONST64U(c) c##uL
-#else
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#endif
-#else
-#error - Need compiler define for CONST64
-#endif
-#endif
-
-/*
- * Use CONST3264/CONST3264U if you want a constant to be
- * treated as a 32-bit number on 32-bit compiles and
- * a 64-bit number on 64-bit compiles. Useful in the case
- * of shifts, like (CONST3264U(1) << x), where x could be
- * more than 31 on a 64-bit compile.
- */
-
-#ifdef VM_X86_64
- #define CONST3264(a) CONST64(a)
- #define CONST3264U(a) CONST64U(a)
-#else
- #define CONST3264(a) (a)
- #define CONST3264U(a) (a)
-#endif
-
-#define MIN_INT32 ((int32)0x80000000)
-#define MAX_INT32 ((int32)0x7fffffff)
-
-#define MIN_UINT32 ((uint32)0)
-#define MAX_UINT32 ((uint32)0xffffffff)
-
-#define MIN_INT64 (CONST64(0x8000000000000000))
-#define MAX_INT64 (CONST64(0x7fffffffffffffff))
-
-#define MIN_UINT64 (CONST64U(0))
-#define MAX_UINT64 (CONST64U(0xffffffffffffffff))
-
-typedef uint8 *TCA; /* Pointer into TC (usually). */
-
-/*
- * Type big enough to hold an integer between 0..100
- */
-typedef uint8 Percent;
-#define AsPercent(v) ((Percent)(v))
-#define CHOOSE_PERCENT AsPercent(101)
-
-
-typedef uintptr_t VA;
-typedef uintptr_t VPN;
-
-typedef uint64 PA;
-typedef uint32 PPN;
-
-typedef uint64 PhysMemOff;
-typedef uint64 PhysMemSize;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 BA;
-#endif
-typedef uint32 BPN;
-typedef uint32 PageNum;
-typedef unsigned MemHandle;
-typedef int32 World_ID;
-
-#define INVALID_WORLD_ID ((World_ID)-1)
-
-typedef World_ID User_CartelID;
-#define INVALID_CARTEL_ID INVALID_WORLD_ID
-
-typedef User_CartelID User_SessionID;
-#define INVALID_SESSION_ID INVALID_CARTEL_ID
-
-typedef User_CartelID User_CartelGroupID;
-#define INVALID_CARTELGROUP_ID INVALID_CARTEL_ID
-
-typedef uint32 Worldlet_ID;
-#define INVALID_WORLDLET_ID ((Worldlet_ID)-1)
-
-/* world page number */
-typedef uint32 WPN;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 MA;
-typedef uint32 MPN;
-#endif
-
-/*
- * This type should be used for variables that contain sector
- * position/quantity.
- */
-typedef uint64 SectorType;
-
-/*
- * Linear address
- */
-
-typedef uintptr_t LA;
-typedef uintptr_t LPN;
-#define LA_2_LPN(_la) ((_la) >> PAGE_SHIFT)
-#define LPN_2_LA(_lpn) ((_lpn) << PAGE_SHIFT)
-
-#define LAST_LPN ((((LA) 1) << (8 * sizeof(LA) - PAGE_SHIFT)) - 1)
-#define LAST_LPN32 ((((LA32)1) << (8 * sizeof(LA32) - PAGE_SHIFT)) - 1)
-#define LAST_LPN64 ((((LA64)1) << (8 * sizeof(LA64) - PAGE_SHIFT)) - 1)
-
-/* Valid bits in a LPN. */
-#define LPN_MASK LAST_LPN
-#define LPN_MASK32 LAST_LPN32
-#define LPN_MASK64 LAST_LPN64
-
-/*
- * On 64 bit platform, address and page number types default
- * to 64 bit. When we need to represent a 32 bit address, we use
- * types defined below.
- *
- * On 32 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint32 VA32;
-typedef uint32 VPN32;
-typedef uint32 LA32;
-typedef uint32 LPN32;
-typedef uint32 PA32;
-typedef uint32 PPN32;
-typedef uint32 MA32;
-typedef uint32 MPN32;
-
-/*
- * On 64 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint64 VA64;
-typedef uint64 VPN64;
-typedef uint64 LA64;
-typedef uint64 LPN64;
-typedef uint64 PA64;
-typedef uint64 PPN64;
-typedef uint64 MA64;
-typedef uint64 MPN64;
-
-/*
- * VA typedefs for user world apps.
- */
-typedef VA32 UserVA32;
-typedef VA64 UserVA64;
-typedef UserVA64 UserVAConst; /* Userspace ptr to data that we may only read. */
-typedef UserVA32 UserVA32Const; /* Userspace ptr to data that we may only read. */
-typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */
-#ifdef VMKERNEL
-typedef UserVA64 UserVA;
-#else
-typedef void * UserVA;
-#endif
-
-
-/*
- * Maximal possible PPN value (errors too) that PhysMem can handle.
- * Must be at least as large as MAX_PPN which is the maximum PPN
- * for any region other than buserror.
- */
-#define PHYSMEM_MAX_PPN ((PPN)0xffffffff)
-#define MAX_PPN ((PPN)0x1fffffff) /* Maximal observable PPN value. */
-#define INVALID_PPN ((PPN)0xffffffff)
-
-#define INVALID_BPN ((BPN) 0x1fffffff)
-
-#define INVALID_MPN ((MPN)-1)
-#define MEMREF_MPN ((MPN)-2)
-#define RESERVED_MPN ((MPN) 0)
-/* Support 43 bits of address space. */
-#define MAX_MPN ((MPN)0x7fffffff)
-
-#define INVALID_LPN ((LPN)-1)
-#define INVALID_VPN ((VPN)-1)
-#define INVALID_LPN64 ((LPN64)-1)
-#define INVALID_PAGENUM ((PageNum)-1)
-#define INVALID_WPN ((WPN) -1)
-
-
-/*
- * Format modifier for printing VA, LA, and VPN.
- * Use them like this: Log("%#"FMTLA"x\n", laddr)
- */
-
-#if defined(VMM64) || defined(FROBOS64) || vm_x86_64 || defined __APPLE__
-# define FMTLA "l"
-# define FMTVA "l"
-# define FMTVPN "l"
-#else
-# define FMTLA ""
-# define FMTVA ""
-# define FMTVPN ""
-#endif
-
-#ifndef EXTERN
-#define EXTERN extern
-#endif
-#define CONST const
-
-
-#ifndef INLINE
-# ifdef _MSC_VER
-# define INLINE __inline
-# else
-# define INLINE inline
-# endif
-#endif
-
-
-/*
- * Annotation for data that may be exported into a DLL and used by other
- * apps that load that DLL and import the data.
- */
-#if defined(_WIN32) && defined(VMX86_IMPORT_DLLDATA)
-# define VMX86_EXTERN_DATA extern __declspec(dllimport)
-#else // !_WIN32
-# define VMX86_EXTERN_DATA extern
-#endif
-
-#if defined(_WIN32) && !defined(VMX86_NO_THREADS)
-#define THREADSPECIFIC __declspec(thread)
-#else
-#define THREADSPECIFIC
-#endif
-
-/*
- * Due to the wonderful "registry redirection" feature introduced in
- * 64-bit Windows, if you access any key under HKLM\Software in 64-bit
- * code, you need to open/create/delete that key with
- * VMKEY_WOW64_32KEY if you want a consistent view with 32-bit code.
- */
-
-#ifdef _WIN32
-#ifdef _WIN64
-#define VMW_KEY_WOW64_32KEY KEY_WOW64_32KEY
-#else
-#define VMW_KEY_WOW64_32KEY 0x0
-#endif
-#endif
-
-
-/*
- * Consider the following reasons functions are inlined:
- *
- * 1) inlined for performance reasons
- * 2) inlined because it's a single-use function
- *
- * Functions which meet only condition 2 should be marked with this
- * inline macro; It is not critical to be inlined (but there is a
- * code-space & runtime savings by doing so), so when other callers
- * are added the inline-ness should be removed.
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-/*
- * Starting at version 3.3, gcc does not always inline functions marked
- * 'inline' (it depends on their size). To force gcc to do so, one must use the
- * extra __always_inline__ attribute.
- */
-# define INLINE_SINGLE_CALLER INLINE __attribute__((__always_inline__))
-# if defined(VMM) \
- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
-# warning Verify INLINE_SINGLE_CALLER '__always_inline__' attribute (did \
- monitor size change?)
-# endif
-#else
-# define INLINE_SINGLE_CALLER INLINE
-#endif
-
-/*
- * Used when a hard guaranteed of no inlining is needed. Very few
- * instances need this since the absence of INLINE is a good hint
- * that gcc will not do inlining.
- */
-
-#if defined(__GNUC__) && defined(VMM)
-#define ABSOLUTELY_NOINLINE __attribute__((__noinline__))
-#endif
-
-/*
- * Attributes placed on function declarations to tell the compiler
- * that the function never returns.
- */
-
-#ifdef _MSC_VER
-#define NORETURN __declspec(noreturn)
-#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9)
-#define NORETURN __attribute__((__noreturn__))
-#else
-#define NORETURN
-#endif
-
-/*
- * GCC 3.2 inline asm needs the + constraint for input/ouput memory operands.
- * Older GCCs don't know about it --hpreg
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
-# define VM_ASM_PLUS 1
-#else
-# define VM_ASM_PLUS 0
-#endif
-
-/*
- * Branch prediction hints:
- * LIKELY(exp) - Expression exp is likely TRUE.
- * UNLIKELY(exp) - Expression exp is likely FALSE.
- * Usage example:
- * if (LIKELY(excCode == EXC_NONE)) {
- * or
- * if (UNLIKELY(REAL_MODE(vc))) {
- *
- * We know how to predict branches on gcc3 and later (hopefully),
- * all others we don't so we do nothing.
- */
-
-#if (__GNUC__ >= 3)
-/*
- * gcc3 uses __builtin_expect() to inform the compiler of an expected value.
- * We use this to inform the static branch predictor. The '!!' in LIKELY
- * will convert any !=0 to a 1.
- */
-#define LIKELY(_exp) __builtin_expect(!!(_exp), 1)
-#define UNLIKELY(_exp) __builtin_expect((_exp), 0)
-#else
-#define LIKELY(_exp) (_exp)
-#define UNLIKELY(_exp) (_exp)
-#endif
-
-/*
- * GCC's argument checking for printf-like functions
- * This is conditional until we have replaced all `"%x", void *'
- * with `"0x%08x", (uint32) void *'. Note that %p prints different things
- * on different platforms. Argument checking is enabled for the
- * vmkernel, which has already been cleansed.
- *
- * fmtPos is the position of the format string argument, beginning at 1
- * varPos is the position of the variable argument, beginning at 1
- */
-
-#if defined(__GNUC__)
-# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
-#else
-# define PRINTF_DECL(fmtPos, varPos)
-#endif
-
-#if defined(__GNUC__)
-# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
-#else
-# define SCANF_DECL(fmtPos, varPos)
-#endif
-
-/*
- * UNUSED_PARAM should surround the parameter name and type declaration,
- * e.g. "int MyFunction(int var1, UNUSED_PARAM(int var2))"
- *
- */
-
-#ifndef UNUSED_PARAM
-# if defined(__GNUC__)
-# define UNUSED_PARAM(_parm) _parm __attribute__((__unused__))
-# else
-# define UNUSED_PARAM(_parm) _parm
-# endif
-#endif
-
-/*
- * REGPARM defaults to REGPARM3, i.e., a requent that gcc
- * puts the first three arguments in registers. (It is fine
- * if the function has fewer than three args.) Gcc only.
- * Syntactically, put REGPARM where you'd put INLINE or NORETURN.
- */
-
-#if defined(__GNUC__)
-# define REGPARM0 __attribute__((regparm(0)))
-# define REGPARM1 __attribute__((regparm(1)))
-# define REGPARM2 __attribute__((regparm(2)))
-# define REGPARM3 __attribute__((regparm(3)))
-# define REGPARM REGPARM3
-#else
-# define REGPARM0
-# define REGPARM1
-# define REGPARM2
-# define REGPARM3
-# define REGPARM
-#endif
-
-/*
- * ALIGNED specifies minimum alignment in "n" bytes.
- */
-
-#ifdef __GNUC__
-#define ALIGNED(n) __attribute__((__aligned__(n)))
-#else
-#define ALIGNED(n)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_OFFSET_CHECK -- */ /**
- *
- * \brief Check if the actual offsef of a member in a structure
- * is what is expected
- *
- *
- * \param[in] STRUCT Structure the member is a part of.
- * \param[in] MEMBER Member to check the offset of.
- * \param[in] OFFSET Expected offset of MEMBER in STRUCTURE.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to OFFSET to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == (OFFSET + DEBUG_EXTRA))
-#else
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == OFFSET)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_SIZE_CHECK -- */ /**
- *
- * \brief Check if the actual size of a structure is what is expected
- *
- *
- * \param[in] STRUCT Structure whose size is to be checked.
- * \param[in] SIZE Expected size of STRUCT.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to SIZE to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == (SIZE + DEBUG_EXTRA))
-#else
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == SIZE)
-#endif
-
-/*
- * __func__ is a stringified function name that is part of the C99 standard. The block
- * below defines __func__ on older systems where the compiler does not support that
- * macro.
- */
-#if defined(__GNUC__) \
- && ((__GNUC__ == 2 && __GNUC_MINOR < 96) \
- || (__GNUC__ < 2))
-# define __func__ __FUNCTION__
-#endif
-
-/*
- * Once upon a time, this was used to silence compiler warnings that
- * get generated when the compiler thinks that a function returns
- * when it is marked noreturn. Don't do it. Use NOT_REACHED().
- */
-
-#define INFINITE_LOOP() do { } while (1)
-
-/*
- * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_
- * is defined. Use the same logic here so we don't define it twice. [greg]
- */
-#ifdef __FreeBSD__
-# ifdef _BSD_SIZE_T_
-# undef _BSD_SIZE_T_
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# ifdef _BSD_SSIZE_T_
-# undef _BSD_SSIZE_T_
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#else
-# ifndef _SIZE_T
-# define _SIZE_T
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(ssize_t) && \
- !defined(__ssize_t_defined) && !defined(_SSIZE_T_DECLARED)
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#endif
-
-/*
- * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The pid is %"FMTPID".\n", pid);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTPID "d"
-# else
-# define FMTPID "lu"
-# endif
-#else
-# define FMTPID "d"
-#endif
-
-/*
- * Format modifier for printing uid_t. On Solaris 10 and earlier, uid_t
- * is a ulong, but on other platforms it's an unsigned int.
- * Use this like this: printf("The uid is %"FMTUID".\n", uid);
- */
-#if defined(sun) && !defined(SOL11)
-# ifdef VM_X86_64
-# define FMTUID "u"
-# else
-# define FMTUID "lu"
-# endif
-#else
-# define FMTUID "u"
-#endif
-
-/*
- * Format modifier for printing mode_t. On sun the mode_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The mode is %"FMTMODE".\n", mode);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTMODE "o"
-# else
-# define FMTMODE "lo"
-# endif
-#else
-# define FMTMODE "o"
-#endif
-
-/*
- * Format modifier for printing time_t. Most platforms define a time_t to be
- * a long int, but on FreeBSD (as of 5.0, it seems), the time_t is a signed
- * size quantity. Refer to the definition of FMTSZ to see why we need silly
- * preprocessor arithmetic.
- * Use this like this: printf("The mode is %"FMTTIME".\n", time);
- */
-#if defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) >= 5)
-# define FMTTIME FMTSZ"d"
-#else
-# define FMTTIME "ld"
-#endif
-
-/*
- * Define MXSemaHandle here so both vmmon and vmx see this definition.
- */
-
-#ifdef _WIN32
-typedef uintptr_t MXSemaHandle;
-#else
-typedef int MXSemaHandle;
-#endif
-
-/*
- * Define type for poll device handles.
- */
-
-#ifdef _WIN32
-typedef uintptr_t PollDevHandle;
-#else
-typedef int PollDevHandle;
-#endif
-
-/*
- * Define the utf16_t type.
- */
-
-#if defined(_WIN32) && defined(_NATIVE_WCHAR_T_DEFINED)
-typedef wchar_t utf16_t;
-#else
-typedef uint16 utf16_t;
-#endif
-
-#endif /* _VM_BASIC_TYPES_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef VM_DEVICE_VERSION_H
-#define VM_DEVICE_VERSION_H
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMCORE
-#include "includeCheck.h"
-
-#ifdef _WIN32
-#include "guiddef.h"
-#endif
-
-/* LSILogic 53C1030 Parallel SCSI controller
- * LSILogic SAS1068 SAS controller
- */
-#define PCI_VENDOR_ID_LSILOGIC 0x1000
-#define PCI_DEVICE_ID_LSI53C1030 0x0030
-#define PCI_DEVICE_ID_LSISAS1068 0x0054
-
-/* Our own PCI IDs
- * VMware SVGA II (Unified VGA)
- * VMware SVGA (PCI Accelerator)
- * VMware vmxnet (Idealized NIC)
- * VMware vmxscsi (Abortive idealized SCSI controller)
- * VMware chipset (Subsystem ID for our motherboards)
- * VMware e1000 (Subsystem ID)
- * VMware vmxnet3 (Uniform Pass Through NIC)
- */
-#define PCI_VENDOR_ID_VMWARE 0x15AD
-#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
-#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
-#define PCI_DEVICE_ID_VMWARE_NET 0x0720
-#define PCI_DEVICE_ID_VMWARE_SCSI 0x0730
-#define PCI_DEVICE_ID_VMWARE_VMCI 0x0740
-#define PCI_DEVICE_ID_VMWARE_CHIPSET 0x1976
-#define PCI_DEVICE_ID_VMWARE_82545EM 0x0750 /* single port */
-#define PCI_DEVICE_ID_VMWARE_82546EB 0x0760 /* dual port */
-#define PCI_DEVICE_ID_VMWARE_EHCI 0x0770
-#define PCI_DEVICE_ID_VMWARE_1394 0x0780
-#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
-#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
-#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
-#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
-
-/* The hypervisor device might grow. Please leave room
- * for 7 more subfunctions.
- */
-#define PCI_DEVICE_ID_VMWARE_HYPER 0x0800
-#define PCI_DEVICE_ID_VMWARE_VMI 0x0801
-
-#define PCI_DEVICE_VMI_CLASS 0x05
-#define PCI_DEVICE_VMI_SUBCLASS 0x80
-#define PCI_DEVICE_VMI_INTERFACE 0x00
-#define PCI_DEVICE_VMI_REVISION 0x01
-
-/* From linux/pci_ids.h:
- * AMD Lance Ethernet controller
- * BusLogic SCSI controller
- * Ensoniq ES1371 sound controller
- */
-#define PCI_VENDOR_ID_AMD 0x1022
-#define PCI_DEVICE_ID_AMD_VLANCE 0x2000
-#define PCI_VENDOR_ID_BUSLOGIC 0x104B
-#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
-#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
-#define PCI_VENDOR_ID_ENSONIQ 0x1274
-#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
-
-/* From linux/pci_ids.h:
- * Intel 82439TX (430 HX North Bridge)
- * Intel 82371AB (PIIX4 South Bridge)
- * Intel 82443BX (440 BX North Bridge and AGP Bridge)
- * Intel 82545EM (e1000, server adapter, single port)
- * Intel 82546EB (e1000, server adapter, dual port)
- * Intel ICH7_16 (High Definition Audio controller)
- * Intel HECI (as embedded in ich9m)
- */
-#define PCI_VENDOR_ID_INTEL 0x8086
-#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
-#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
-#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
-#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
-#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
-#define PCI_DEVICE_ID_INTEL_82443BX 0x7190
-#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
-#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 /* Used when no AGP support */
-#define PCI_DEVICE_ID_INTEL_82545EM 0x100f
-#define PCI_DEVICE_ID_INTEL_82546EB 0x1010
-#define PCI_DEVICE_ID_INTEL_ICH7_16 0x27d8
-#define PCI_DEVICE_ID_INTEL_HECI 0x2a74
-
-
-/************* Strings for IDE Identity Fields **************************/
-#define VIDE_ID_SERIAL_STR "00000000000000000001" /* Must be 20 Bytes */
-#define VIDE_ID_FIRMWARE_STR "00000001" /* Must be 8 Bytes */
-
-/* No longer than 40 Bytes */
-#define VIDE_ATA_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE Hard Drive"
-#define VIDE_ATAPI_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE CDROM Drive"
-
-#define ATAPI_VENDOR_ID "NECVMWar" /* Must be 8 Bytes */
-#define ATAPI_PRODUCT_ID PRODUCT_GENERIC_NAME " IDE CDROM" /* Must be 16 Bytes */
-#define ATAPI_REV_LEVEL "1.00" /* Must be 4 Bytes */
-
-#define IDE_NUM_INTERFACES 2 /* support for two interfaces */
-#define IDE_DRIVES_PER_IF 2
-
-/************* Strings for SCSI Identity Fields **************************/
-#define SCSI_DISK_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI Hard Drive"
-#define SCSI_DISK_VENDOR_NAME COMPANY_NAME
-#define SCSI_DISK_REV_LEVEL "1.0"
-#define SCSI_CDROM_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI CDROM Drive"
-#define SCSI_CDROM_VENDOR_NAME COMPANY_NAME
-#define SCSI_CDROM_REV_LEVEL "1.0"
-
-/************* SCSI implementation limits ********************************/
-#define SCSI_MAX_CONTROLLERS 4 // Need more than 1 for MSCS clustering
-#define SCSI_MAX_DEVICES 16 // BT-958 emulates only 16
-#define SCSI_IDE_CHANNEL SCSI_MAX_CONTROLLERS
-#define SCSI_IDE_HOSTED_CHANNEL (SCSI_MAX_CONTROLLERS + 1)
-#define SCSI_MAX_CHANNELS (SCSI_MAX_CONTROLLERS + 2)
-
-/************* Strings for the VESA BIOS Identity Fields *****************/
-#define VBE_OEM_STRING COMPANY_NAME " SVGA"
-#define VBE_VENDOR_NAME COMPANY_NAME
-#define VBE_PRODUCT_NAME PRODUCT_GENERIC_NAME
-
-/************* PCI implementation limits ********************************/
-#define PCI_MAX_BRIDGES 15
-
-/************* Ethernet implementation limits ***************************/
-#define MAX_ETHERNET_CARDS 10
-
-/************* PCI Passthrough implementation limits ********************/
-#define MAX_PCI_PASSTHRU_DEVICES 2
-
-/************* USB implementation limits ********************************/
-#define MAX_USB_DEVICES_PER_HOST_CONTROLLER 127
-
-/************* Strings for Host USB Driver *******************************/
-
-#ifdef _WIN32
-
-/*
- * Globally unique ID for the VMware device interface. Define INITGUID before including
- * this header file to instantiate the variable.
- */
-DEFINE_GUID(GUID_DEVICE_INTERFACE_VMWARE_USB_DEVICES,
-0x2da1fe75, 0xaab3, 0x4d2c, 0xac, 0xdf, 0x39, 0x8, 0x8c, 0xad, 0xa6, 0x65);
-
-/*
- * Globally unique ID for the VMware device setup class.
- */
-DEFINE_GUID(GUID_CLASS_VMWARE_USB_DEVICES,
-0x3b3e62a5, 0x3556, 0x4d7e, 0xad, 0xad, 0xf5, 0xfa, 0x3a, 0x71, 0x2b, 0x56);
-
-/*
- * This string defines the device ID string of a VMware USB device.
- * The format is USB\Vid_XXXX&Pid_YYYY, where XXXX and YYYY are the
- * hexadecimal representations of the vendor and product ids, respectively.
- *
- * The official vendor ID for VMware, Inc. is 0x0E0F.
- * The product id for USB generic devices is 0x0001.
- */
-#define USB_VMWARE_DEVICE_ID_WIDE L"USB\\Vid_0E0F&Pid_0001"
-#define USB_DEVICE_ID_LENGTH (sizeof(USB_VMWARE_DEVICE_ID_WIDE) / sizeof(WCHAR))
-
-#ifdef UNICODE
-#define USB_PNP_SETUP_CLASS_NAME L"VMwareUSBDevices"
-#define USB_PNP_DRIVER_NAME L"vmusb"
-#else
-#define USB_PNP_SETUP_CLASS_NAME "VMwareUSBDevices"
-#define USB_PNP_DRIVER_NAME "vmusb"
-#endif
-#endif
-
-#endif /* VM_DEVICE_VERSION_H */
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmxnet3
-PRODUCT := @PRODUCT@
+PRODUCT := tools
# Grep program
GREP = /bin/grep
#### VMware vmxnet3 Makefile to be distributed externally
####
-INCLUDE := -I.
+INCLUDE += -I.
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/netif_num_params.c, -DVMW_NETIF_SINGLE_NAPI_PARM, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/netif_num_params.c, , -DVMW_NETIF_SINGLE_NAPI_PARM)
obj-m += $(DRIVER).o
CC_OPTS := -g3 -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS)
-INCLUDE := -I$(HEADER_DIR)
+INCLUDE += -I$(HEADER_DIR)
INCLUDE += $(shell $(CC) $(CC_OPTS) $(INCLUDE) \
- -E $(SRCROOT)/autoconf/geninclude.c \
+ -E $(AUTOCONF_DIR)/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/netif_num_params.c, -DVMW_NETIF_SINGLE_NAPI_PARM, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/skblin.c, -DVMW_SKB_LINEARIZE_2618, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/netif_num_params.c, , -DVMW_NETIF_SINGLE_NAPI_PARM)
OBJS := vmxnet3.o
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-
-#ifdef CONFIG_X86_VOYAGER
-APATH/mach-voyager
-#endif
-#ifdef CONFIG_X86_VISWS
-APATH/mach-visws
-#endif
-#ifdef CONFIG_X86_NUMAQ
-APATH/mach-numaq
-#endif
-#ifdef CONFIG_X86_BIGSMP
-APATH/mach-bigsmp
-#endif
-#ifdef CONFIG_X86_SUMMIT
-APATH/mach-summit
-#endif
-#ifdef CONFIG_X86_GENERICARCH
-APATH/mach-generic
-#endif
-APATH/mach-default
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Detect whether skb_linearize takes one or two arguments.
- */
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
-/*
- * Since 2.6.18 all kernels have single-argument skb_linearize. For
- * older kernels use autodetection. Not using autodetection on newer
- * kernels saves us from compile failure on some post 2.6.18 kernels
- * which do not have selfcontained skbuff.h.
- */
-
-#include <linux/skbuff.h>
-
-int test_skb_linearize(struct sk_buff *skb)
-{
- return skb_linearize(skb);
-}
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef _COMPAT_ETHTOOL_H
-#define _COMPAT_ETHTOOL_H
-
-/*
- * ethtool is a userspace utility for getting and setting ethernet device
- * settings. Kernel support for it was first published in 2.4.0-test11, but
- * only in 2.4.15 were the ethtool_value struct and the ETHTOOL_GLINK ioctl
- * added to ethtool.h (together, because the ETHTOOL_GLINK ioctl expects a
- * single value response).
- *
- * Likewise, ioctls for getting and setting TSO were published in 2.4.22.
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-# include <linux/ethtool.h>
-
-# ifndef ETHTOOL_GLINK
-# define ETHTOOL_GLINK 0x0a
-
-typedef struct {
- __u32 cmd;
- __u32 data;
-} compat_ethtool_value;
-
-# else
-
-typedef struct ethtool_value compat_ethtool_value;
-# endif
-
-# ifndef ETHTOOL_GTSO
-# define ETHTOOL_GTSO 0x1E
-# define ETHTOOL_STSO 0x1F
-# endif
-#endif
-
-#endif /* _COMPAT_ETHTOOL_H */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_HIGHMEM_H__
-# define __COMPAT_HIGHMEM_H__
-
-
-/*
- * BIGMEM (4 GB) support appeared in 2.3.16: kmap() API added
- * HIGHMEM (4 GB + 64 GB) support appeared in 2.3.23: kmap() API modified
- * In 2.3.27, kmap() API modified again
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 27)
-# include <linux/highmem.h>
-#else
-/* For page_address --hpreg */
-# include <linux/pagemap.h>
-
-# define kmap(_page) (void*)page_address(_page)
-# define kunmap(_page)
-#endif
-
-#endif /* __COMPAT_HIGHMEM_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_init.h: Initialization compatibility wrappers.
- */
-
-#ifndef __COMPAT_INIT_H__
-#define __COMPAT_INIT_H__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-#include <linux/init.h>
-#endif
-
-#ifndef module_init
-#define module_init(x) int init_module(void) { return x(); }
-#endif
-
-#ifndef module_exit
-#define module_exit(x) void cleanup_module(void) { x(); }
-#endif
-
-#endif /* __COMPAT_INIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_INTERRUPT_H__
-# define __COMPAT_INTERRUPT_H__
-
-
-#include <linux/interrupt.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69)
-/*
- * We cannot just define irqreturn_t, as some 2.4.x kernels have
- * typedef void irqreturn_t; for "increasing" backward compatibility.
- */
-typedef void compat_irqreturn_t;
-#define COMPAT_IRQ_NONE
-#define COMPAT_IRQ_HANDLED
-#define COMPAT_IRQ_RETVAL(x)
-#else
-typedef irqreturn_t compat_irqreturn_t;
-#define COMPAT_IRQ_NONE IRQ_NONE
-#define COMPAT_IRQ_HANDLED IRQ_HANDLED
-#define COMPAT_IRQ_RETVAL(x) IRQ_RETVAL(x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
-#define COMPAT_IRQF_DISABLED SA_INTERRUPT
-#define COMPAT_IRQF_SHARED SA_SHIRQ
-#else
-#define COMPAT_IRQF_DISABLED IRQF_DISABLED
-#define COMPAT_IRQF_SHARED IRQF_SHARED
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
-#define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp, struct pt_regs *regs)
-#else
-#define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp)
-#endif
-
-#endif /* __COMPAT_INTERRUPT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_IOPORT_H__
-# define __COMPAT_IOPORT_H__
-
-
-#include <linux/ioport.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-static inline void *
-compat_request_region(unsigned long start, unsigned long len, const char *name)
-{
- if (check_region(start, len)) {
- return NULL;
- }
- request_region(start, len, name);
- return (void*)1;
-}
-#else
-#define compat_request_region(start, len, name) request_region(start, len, name)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 7)
-/* mmap io support starts from 2.3.7, fail the call for kernel prior to that */
-static inline void *
-compat_request_mem_region(unsigned long start, unsigned long len, const char *name)
-{
- return NULL;
-}
-
-static inline void
-compat_release_mem_region(unsigned long start, unsigned long len)
-{
- return;
-}
-#else
-#define compat_request_mem_region(start, len, name) request_mem_region(start, len, name)
-#define compat_release_mem_region(start, len) release_mem_region(start, len)
-#endif
-
-/* these two macro defs are needed by compat_pci_request_region */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15)
-# define IORESOURCE_IO 0x00000100
-# define IORESOURCE_MEM 0x00000200
-#endif
-
-#endif /* __COMPAT_IOPORT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_pci.h: PCI compatibility wrappers.
- */
-
-#ifndef __COMPAT_PCI_H__
-#define __COMPAT_PCI_H__
-
-#include "compat_ioport.h"
-#include <linux/pci.h>
-#ifndef KERNEL_2_1
-# include <linux/bios32.h>
-#endif
-
-
-/* 2.0.x has useless struct pci_dev; remap it to our own */
-#ifndef KERNEL_2_1
-#define pci_dev vmw_pci_driver_instance
-#endif
-
-
-/* 2.0/2.2 does not have pci driver API */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-struct vmw_pci_driver_instance {
- struct vmw_pci_driver_instance *next;
- void *driver_data;
- struct pci_driver *pcidrv;
-#ifdef KERNEL_2_1
- struct pci_dev *pcidev;
-#else
- unsigned char bus;
- unsigned char devfn;
- unsigned int irq;
-#endif
-};
-#endif
-
-
-/* 2.0 has pcibios_* calls only... We have to provide pci_* compatible wrappers. */
-#ifndef KERNEL_2_1
-static inline int
-pci_read_config_byte(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Byte to read
- u8 *value) // OUT: Value read
-{
- return pcibios_read_config_byte(pdev->bus, pdev->devfn, where, value);
-}
-
-static inline int
-pci_read_config_dword(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Dword to read
- u32 *value) // OUT: Value read
-{
- return pcibios_read_config_dword(pdev->bus, pdev->devfn, where, value);
-}
-
-static inline int
-pci_write_config_dword(struct pci_dev *pdev, // IN: PCI slot
- unsigned char where, // IN: Dword to write
- u32 value) // IN: Value to write
-{
- return pcibios_write_config_dword(pdev->bus, pdev->devfn, where, value);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * compat_pci_name --
- *
- * Return human readable PCI slot name. Note that some implementations
- * return a pointer to the static storage, so returned value may be
- * overwritten by subsequent calls to this function.
- *
- * Results:
- * Returns pointer to the string with slot name.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-#define compat_pci_name(pdev) pci_name(pdev)
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-#define compat_pci_name(pdev) (pdev)->slot_name
-#elif defined(KERNEL_2_1)
-static inline const char*
-compat_pci_name(struct pci_dev* pdev)
-{
- static char slot_name[12];
- sprintf(slot_name, "%02X:%02X.%X", pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
- return slot_name;
-}
-#else
-static inline const char*
-compat_pci_name(struct pci_dev* pdev)
-{
- static char slot_name[12];
- sprintf(slot_name, "%02X:%02X.%X", pdev->bus,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
- return slot_name;
-}
-#endif
-
-
-/* pci_resource_start comes in 4 flavors - 2.0, 2.2, early 2.3, 2.4+ */
-#ifndef KERNEL_2_1
-static inline unsigned long
-compat_pci_resource_start(struct pci_dev *pdev,
- unsigned int index)
-{
- u32 addr;
-
- if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
- printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
- index, compat_pci_name(pdev));
- return ~0UL;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return addr & PCI_BASE_ADDRESS_IO_MASK;
- } else {
- return addr & PCI_BASE_ADDRESS_MEM_MASK;
- }
-}
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
-# define compat_pci_resource_start(dev, index) \
- (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
- ? ((dev)->base_address[index] & PCI_BASE_ADDRESS_IO_MASK) \
- : ((dev)->base_address[index] & PCI_BASE_ADDRESS_MEM_MASK))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)
-# define compat_pci_resource_start(dev, index) \
- ((dev)->resource[index].start)
-#else
-# define compat_pci_resource_start(dev, index) \
- pci_resource_start(dev, index)
-#endif
-
-/* since 2.3.15, a new set of s/w res flags IORESOURCE_ is introduced,
- * we fake them by returning either IORESOURCE_{IO, MEM} prior to 2.3.15 since
- * this is what compat_pci_request_region uses
- */
-#ifndef KERNEL_2_1
-static inline unsigned long
-compat_pci_resource_flags(struct pci_dev *pdev,
- unsigned int index)
-{
- u32 addr;
-
- if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) {
- printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n",
- index, compat_pci_name(pdev));
- return ~0UL;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return IORESOURCE_IO;
- } else {
- return IORESOURCE_MEM;
- }
-}
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1)
-# define compat_pci_resource_flags(dev, index) \
- (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \
- ? IORESOURCE_IO: IORESOURCE_MEM)
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15)
- /* IORESOURCE_xxx appeared in 2.3.15 and is set in resource[].flags */
-# define compat_pci_resource_flags(dev, index) ((dev)->resource[index].flags)
-#else
-# define compat_pci_resource_flags(dev, index) pci_resource_flags(dev, index)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
-static inline unsigned long
-compat_pci_resource_len(struct pci_dev *pdev, // IN
- unsigned int index) // IN
-{
- u32 addr, mask;
- unsigned char reg = PCI_BASE_ADDRESS_0 + index * 4;
-
- if (pci_read_config_dword(pdev, reg, &addr) || addr == 0xFFFFFFFF) {
- return 0;
- }
-
- pci_write_config_dword(pdev, reg, 0xFFFFFFFF);
- pci_read_config_dword(pdev, reg, &mask);
- pci_write_config_dword(pdev, reg, addr);
-
- if (mask == 0 || mask == 0xFFFFFFFF) {
- return 0;
- }
- if (addr & PCI_BASE_ADDRESS_SPACE) {
- return 65536 - (mask & PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
- } else {
- return -(mask & PCI_BASE_ADDRESS_MEM_MASK);
- }
-}
-#else
-#define compat_pci_resource_len(dev, index) pci_resource_len(dev, index)
-#endif
-
-/* pci_request_region appears in 2.4.20 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
-static inline int
-compat_pci_request_region(struct pci_dev *pdev, int bar, char *name)
-{
- if (compat_pci_resource_len(pdev, bar) == 0) {
- return 0;
- }
-
- if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
- if (!compat_request_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar),
- name)) {
- return -EBUSY;
- }
- } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
- if (!compat_request_mem_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar),
- name)) {
- return -EBUSY;
- }
- }
-
- return 0;
-}
-
-static inline void
-compat_pci_release_region(struct pci_dev *pdev, int bar)
-{
- if (compat_pci_resource_len(pdev, bar) != 0) {
- if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
- release_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar));
- } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
- compat_release_mem_region(compat_pci_resource_start(pdev, bar),
- compat_pci_resource_len(pdev, bar));
- }
- }
-}
-#else
-#define compat_pci_request_region(pdev, bar, name) pci_request_region(pdev, bar, name)
-#define compat_pci_release_region(pdev, bar) pci_release_region(pdev, bar)
-#endif
-
-/* pci_request_regions appeears in 2.4.3 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)
-static inline int
-compat_pci_request_regions(struct pci_dev *pdev, char *name)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- if (compat_pci_request_region(pdev, i, name)) {
- goto release;
- }
- }
- return 0;
-
-release:
- while (--i >= 0) {
- compat_pci_release_region(pdev, i);
- }
- return -EBUSY;
-}
-static inline void
-compat_pci_release_regions(struct pci_dev *pdev)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- compat_pci_release_region(pdev, i);
- }
-}
-#else
-#define compat_pci_request_regions(pdev, name) pci_request_regions(pdev, name)
-#define compat_pci_release_regions(pdev) pci_release_regions(pdev)
-#endif
-
-/* pci_enable_device is available since 2.4.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define compat_pci_enable_device(pdev) (0)
-#else
-#define compat_pci_enable_device(pdev) pci_enable_device(pdev)
-#endif
-
-
-/* pci_set_master is available since 2.2.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-#define compat_pci_set_master(pdev) (0)
-#else
-#define compat_pci_set_master(pdev) pci_set_master(pdev)
-#endif
-
-
-/* pci_disable_device is available since 2.4.4 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 4)
-#define compat_pci_disable_device(pdev) do {} while (0)
-#else
-#define compat_pci_disable_device(pdev) pci_disable_device(pdev)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-/*
- * Devices supported by particular pci driver. While 2.4+ kernels
- * can do match on subsystem and class too, we support match on
- * vendor/device IDs only.
- */
-struct pci_device_id {
- unsigned int vendor, device;
- unsigned long driver_data;
-};
-#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev)
-
-/* PCI driver */
-struct pci_driver {
- const char *name;
- const struct pci_device_id *id_table;
- int (*probe)(struct pci_dev* dev, const struct pci_device_id* id);
- void (*remove)(struct pci_dev* dev);
-};
-
-
-/*
- * Note that this is static variable. Maybe everything below should be in
- * separate compat_pci.c file, but currently only user of this file is vmxnet,
- * and vmxnet has only one file, so it is fine. Also with vmxnet all
- * functions below are called just once, so difference between 'inline' and
- * separate compat_pci.c should be very small.
- */
-
-static struct vmw_pci_driver_instance *pci_driver_instances = NULL;
-
-#ifdef KERNEL_2_1
-#define vmw_pci_device(instance) (instance)->pcidev
-#else
-#define vmw_pci_device(instance) (instance)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_register_driver --
- *
- * Create driver instances for all matching PCI devices in the box.
- *
- * Results:
- * Returns 0 for success, negative error value for failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static inline int
-pci_register_driver(struct pci_driver *drv)
-{
- const struct pci_device_id *chipID;
-
- for (chipID = drv->id_table; chipID->vendor; chipID++) {
-#ifdef KERNEL_2_1
- struct pci_dev *pdev;
-
- for (pdev = NULL;
- (pdev = pci_find_device(chipID->vendor, chipID->device, pdev)) != NULL; ) {
-#else
- int adapter;
- unsigned char bus, devfn, irq;
-
- for (adapter = 0;
- pcibios_find_device(chipID->vendor, chipID->device, adapter,
- &bus, &devfn) == 0;
- adapter++) {
-#endif
- struct vmw_pci_driver_instance *pdi;
- int err;
-
- pdi = kmalloc(sizeof *pdi, GFP_KERNEL);
- if (!pdi) {
- printk(KERN_ERR "Not enough memory.\n");
- break;
- }
- pdi->pcidrv = drv;
-#ifdef KERNEL_2_1
- pdi->pcidev = pdev;
-#else
- pdi->bus = bus;
- pdi->devfn = devfn;
- if (pci_read_config_byte(pdi, PCI_INTERRUPT_LINE, &irq)) {
- pdi->irq = -1;
- } else {
- pdi->irq = irq;
- }
-#endif
- pdi->driver_data = NULL;
- pdi->next = pci_driver_instances;
- pci_driver_instances = pdi;
- err = drv->probe(vmw_pci_device(pdi), chipID);
- if (err) {
- pci_driver_instances = pdi->next;
- kfree(pdi);
- }
- }
- }
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * compat_pci_unregister_driver --
- *
- * Shut down PCI driver - unbind all device instances from driver.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static inline void
-pci_unregister_driver(struct pci_driver *drv)
-{
- struct vmw_pci_driver_instance **ppdi;
-
- ppdi = &pci_driver_instances;
- while (1) {
- struct vmw_pci_driver_instance *pdi = *ppdi;
-
- if (!pdi) {
- break;
- }
- if (pdi->pcidrv == drv) {
- drv->remove(vmw_pci_device(pdi));
- *ppdi = pdi->next;
- kfree(pdi);
- } else {
- ppdi = &pdi->next;
- }
- }
-}
-#else
-/* provide PCI_DEVICE for early 2.4.x kernels */
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif
-#endif
-
-
-/* provide dummy MODULE_DEVICE_TABLE for 2.0/2.2 */
-#ifndef MODULE_DEVICE_TABLE
-#define MODULE_DEVICE_TABLE(bus, devices)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_set_drvdata --
- *
- * Set per-device driver's private data.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * pci_get_drvdata --
- *
- * Retrieve per-device driver's private data.
- *
- * Results:
- * per-device driver's data previously set by pci_set_drvdata,
- * or NULL on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-#ifndef KERNEL_2_1
-/* 2.0.x is simple, we have driver_data directly in pci_dev */
-#define pci_set_drvdata(pdev, data) do { (pdev)->driver_data = (data); } while (0)
-#define pci_get_drvdata(pdev) (pdev)->driver_data
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-/* 2.2.x is trickier, we have to find driver instance first */
-static inline void
-pci_set_drvdata(struct pci_dev *pdev, void* data)
-{
- struct vmw_pci_driver_instance *pdi;
-
- for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
- if (pdi->pcidev == pdev) {
- pdi->driver_data = data;
- return;
- }
- }
- printk(KERN_ERR "pci_set_drvdata issued for unknown device %p\n", pdev);
-}
-
-static inline void *
-pci_get_drvdata(struct pci_dev *pdev)
-{
- struct vmw_pci_driver_instance *pdi;
-
- for (pdi = pci_driver_instances; pdi; pdi = pdi->next) {
- if (pdi->pcidev == pdev) {
- return pdi->driver_data;
- }
- }
- printk(KERN_ERR "pci_get_drvdata issued for unknown device %p\n", pdev);
- return NULL;
-}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)
-# define PCI_DMA_BIDIRECTIONAL 0
-# define PCI_DMA_TODEVICE 1
-# define PCI_DMA_FROMDEVICE 2
-# define PCI_DMA_NONE 3
-#endif
-
-/*
- * Power Management related compat wrappers.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
-# define compat_pci_save_state(pdev) pci_save_state((pdev), NULL)
-# define compat_pci_restore_state(pdev) pci_restore_state((pdev), NULL)
-#else
-# define compat_pci_save_state(pdev) pci_save_state((pdev))
-# define compat_pci_restore_state(pdev) pci_restore_state((pdev))
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
-# define pm_message_t u32
-# define compat_pci_choose_state(pdev, state) (state)
-# define PCI_D0 0
-# define PCI_D3hot 3
-#else
-# define compat_pci_choose_state(pdev, state) pci_choose_state((pdev), (state))
-#endif
-
-/* 2.6.14 changed the PCI shutdown callback */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
-# define COMPAT_PCI_SHUTDOWN(func) .driver = { .shutdown = (func), }
-# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct device *(var))
-# define COMPAT_PCI_TO_DEV(dev) (to_pci_dev(dev))
-#else
-# define COMPAT_PCI_SHUTDOWN(func) .shutdown = (func)
-# define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct pci_dev *(var))
-# define COMPAT_PCI_TO_DEV(dev) (dev)
-#endif
-
-
-#endif /* __COMPAT_PCI_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SKBUFF_H__
-# define __COMPAT_SKBUFF_H__
-
-#include <linux/skbuff.h>
-
-/*
- * When transition from mac/nh/h to skb_* accessors was made, also SKB_WITH_OVERHEAD
- * was introduced.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) || \
- (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 21) && defined(SKB_WITH_OVERHEAD))
-#define compat_skb_mac_header(skb) skb_mac_header(skb)
-#define compat_skb_network_header(skb) skb_network_header(skb)
-#define compat_skb_network_offset(skb) skb_network_offset(skb)
-#define compat_skb_transport_header(skb) skb_transport_header(skb)
-#define compat_skb_transport_offset(skb) skb_transport_offset(skb)
-#define compat_skb_network_header_len(skb) skb_network_header_len(skb)
-#define compat_skb_tail_pointer(skb) skb_tail_pointer(skb)
-#define compat_skb_end_pointer(skb) skb_end_pointer(skb)
-#define compat_skb_ip_header(skb) ((struct iphdr *)skb_network_header(skb))
-#define compat_skb_tcp_header(skb) ((struct tcphdr *)skb_transport_header(skb))
-#define compat_skb_reset_mac_header(skb) skb_reset_mac_header(skb)
-#define compat_skb_set_network_header(skb, off) skb_set_network_header(skb, off)
-#define compat_skb_set_transport_header(skb, off) skb_set_transport_header(skb, off)
-#else
-#define compat_skb_mac_header(skb) (skb)->mac.raw
-#define compat_skb_network_header(skb) (skb)->nh.raw
-#define compat_skb_network_offset(skb) ((skb)->nh.raw - (skb)->data)
-#define compat_skb_transport_header(skb) (skb)->h.raw
-#define compat_skb_transport_offset(skb) ((skb)->h.raw - (skb)->data)
-#define compat_skb_network_header_len(skb) ((skb)->h.raw - (skb)->nh.raw)
-#define compat_skb_tail_pointer(skb) (skb)->tail
-#define compat_skb_end_pointer(skb) (skb)->end
-#define compat_skb_ip_header(skb) (skb)->nh.iph
-#define compat_skb_tcp_header(skb) (skb)->h.th
-#define compat_skb_reset_mac_header(skb) ((skb)->mac.raw = (skb)->data)
-#define compat_skb_set_network_header(skb, off) ((skb)->nh.raw = (skb)->data + (off))
-#define compat_skb_set_transport_header(skb, off) ((skb)->h.raw = (skb)->data + (off))
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) || defined(VMW_SKB_LINEARIZE_2618)
-# define compat_skb_linearize(skb) skb_linearize((skb))
-#else
-
-# if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 0)
-# define compat_skb_linearize(skb) __skb_linearize((skb), GFP_ATOMIC)
-# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4)
-# define compat_skb_linearize(skb) skb_linearize((skb), GFP_ATOMIC)
-# else
-static inline int
-compat_skb_linearize(struct sk_buff *skb)
-{
- return 0;
-}
-# endif
-
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-#define compat_skb_csum_offset(skb) (skb)->csum_offset
-#else
-#define compat_skb_csum_offset(skb) (skb)->csum
-#endif
-
-/*
- * Note that compat_skb_csum_start() has semantic different from kernel's csum_start:
- * kernel's skb->csum_start is offset between start of checksummed area and start of
- * complete skb buffer, while our compat_skb_csum_start(skb) is offset from start
- * of packet itself.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
-#define compat_skb_csum_start(skb) ((skb)->csum_start - skb_headroom(skb))
-#else
-#define compat_skb_csum_start(skb) compat_skb_transport_offset(skb)
-#endif
-
-#if defined(NETIF_F_GSO) /* 2.6.18 and upwards */
-#define compat_skb_mss(skb) (skb_shinfo(skb)->gso_size)
-#else
-#define compat_skb_mss(skb) (skb_shinfo(skb)->tso_size)
-#endif
-
-/* used by both received pkts and outgoing ones */
-#define VM_CHECKSUM_UNNECESSARY CHECKSUM_UNNECESSARY
-
-/* csum status of received pkts */
-#if defined(CHECKSUM_COMPLETE)
-# define VM_RX_CHECKSUM_PARTIAL CHECKSUM_COMPLETE
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW)
-# define VM_RX_CHECKSUM_PARTIAL CHECKSUM_HW
-#else
-# define VM_RX_CHECKSUM_PARTIAL CHECKSUM_PARTIAL
-#endif
-
-/* csum status of outgoing pkts */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW)
-# define VM_TX_CHECKSUM_PARTIAL CHECKSUM_HW
-#else
-# define VM_TX_CHECKSUM_PARTIAL CHECKSUM_PARTIAL
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0))
-# define compat_kfree_skb(skb, type) kfree_skb(skb, type)
-# define compat_dev_kfree_skb(skb, type) dev_kfree_skb(skb, type)
-# define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb(skb, type)
-# define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb(skb, type)
-#else
-# define compat_kfree_skb(skb, type) kfree_skb(skb)
-# define compat_dev_kfree_skb(skb, type) dev_kfree_skb(skb)
-# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43))
-# define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb(skb)
-# define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb(skb)
-# else
-# define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb_any(skb)
-# define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb_irq(skb)
-# endif
-#endif
-
-#ifndef NET_IP_ALIGN
-# define COMPAT_NET_IP_ALIGN 2
-#else
-# define COMPAT_NET_IP_ALIGN NET_IP_ALIGN
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4)
-# define compat_skb_headlen(skb) skb_headlen(skb)
-# define compat_pskb_may_pull(skb, len) pskb_may_pull(skb, len)
-# define compat_skb_is_nonlinear(skb) skb_is_nonlinear(skb)
-#else
-# define compat_skb_headlen(skb) (skb)->len
-# define compat_pskb_may_pull(skb, len) 1
-# define compat_skb_is_nonlinear(skb) 0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
-# define compat_skb_header_cloned(skb) skb_header_cloned(skb)
-#else
-# define compat_skb_header_cloned(skb) 0
-#endif
-#endif /* __COMPAT_SKBUFF_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SLAB_H__
-# define __COMPAT_SLAB_H__
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# include <linux/slab.h>
-#else
-# include <linux/malloc.h>
-#endif
-
-/*
- * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache
- * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and
- * afterwards it was renamed to kmem_cache. Here we keep things simple and use
- * the accepted typedef until it became deprecated, at which point we switch
- * over to the kmem_cache name.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-# define compat_kmem_cache struct kmem_cache
-#else
-# define compat_kmem_cache kmem_cache_t
-#endif
-
-/*
- * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags,
- * constructor, and destructor. Then for some time kernel was asserting that
- * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5
- * arguments - destructor is gone.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR)
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor, NULL)
-#else
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor)
-#endif
-
-/*
- * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to
- * prepare (aka "this"), from which cache it came, and some unused flags. After
- * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped...
- * Since 2.6.27-rc2 everything is different again, and ctor has only one argument.
- *
- * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_3_ARGS
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_2_ARGS
-#endif
-
-#if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \
- compat_kmem_cache *cache, \
- unsigned long flags
-#elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \
- void *arg
-#else
-typedef void compat_kmem_cache_ctor(void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg
-#endif
-
-#endif /* __COMPAT_SLAB_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SPINLOCK_H__
-# define __COMPAT_SPINLOCK_H__
-
-
-/*
- * The spin_lock() API appeared in 2.1.25 in asm/smp_lock.h
- * It moved in 2.1.30 to asm/spinlock.h
- * It moved again in 2.3.18 to linux/spinlock.h
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 18)
-# include <linux/spinlock.h>
-#else
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30)
-# include <asm/spinlock.h>
-# else
-typedef struct {} spinlock_t;
-# define spin_lock_init(lock)
-# define spin_lock(lock)
-# define spin_unlock(lock)
-# define spin_lock_irqsave(lock, flags) do { \
- save_flags(flags); \
- cli(); \
- spin_lock(lock); \
- } while (0)
-# define spin_unlock_irqrestore(lock, flags) do { \
- spin_unlock(lock); \
- restore_flags(flags); \
- } while (0)
-# endif
-#endif
-
-
-/*
- * Preempt support was added during 2.5.x development cycle, and later
- * it was backported to 2.4.x. In 2.4.x backport these definitions
- * live in linux/spinlock.h, that's why we put them here (in 2.6.x they
- * are defined in linux/preempt.h which is included by linux/spinlock.h).
- */
-#ifdef CONFIG_PREEMPT
-#define compat_preempt_disable() preempt_disable()
-#define compat_preempt_enable() preempt_enable()
-#else
-#define compat_preempt_disable() do { } while (0)
-#define compat_preempt_enable() do { } while (0)
-#endif
-
-
-#endif /* __COMPAT_SPINLOCK_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_TIMER_H__
-# define __COMPAT_TIMER_H__
-
-
-/*
- * The del_timer_sync() API appeared in 2.3.43
- * It became reliable in 2.4.0-test3
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-# define compat_del_timer_sync(timer) del_timer_sync(timer)
-#else
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)
- /* 2.3.43 removed asm/softirq.h's reference to bh_base. */
-# include <linux/interrupt.h>
-# endif
-# include <asm/softirq.h>
-
-static inline int
-compat_del_timer_sync(struct timer_list *timer) // IN
-{
- int wasPending;
-
- start_bh_atomic();
- wasPending = del_timer(timer);
- end_bh_atomic();
-
- return wasPending;
-}
-#endif
-
-
-/*
- * The msleep_interruptible() API appeared in 2.6.9.
- * It is based on the msleep() API, which appeared in 2.4.29.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
-# include <linux/delay.h>
-# define compat_msleep_interruptible(msecs) msleep_interruptible(msecs)
-# define compat_msleep(msecs) msleep(msecs)
-#else
-# include <linux/sched.h>
-/*
- * msecs_to_jiffies appeared in 2.6.7. For earlier kernels,
- * fall back to slow-case code (we don't use this operation
- * enough to need the performance).
- */
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7)
-# define msecs_to_jiffies(msecs) (((msecs) * HZ + 999) / 1000)
-# endif
-/*
- * set_current_state appeared in 2.2.18.
- */
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
-# define set_current_state(a) do { current->state = (a); } while(0)
-# endif
-
-static inline void
-compat_msleep_interruptible(unsigned long msecs) // IN
-{
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(msecs) + 1);
-}
-
-static inline void
-compat_msleep(unsigned long msecs) // IN
-{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(msecs_to_jiffies(msecs) + 1);
-}
-#endif
-
-
-/*
- * There is init_timer_deferrable() since 2.6.22.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
-# define compat_init_timer_deferrable(timer) init_timer_deferrable(timer)
-#else
-# define compat_init_timer_deferrable(timer) init_timer(timer)
-#endif
-
-
-#endif /* __COMPAT_TIMER_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_WORKQUEUE_H__
-# define __COMPAT_WORKQUEUE_H__
-
-#include <linux/kernel.h>
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)
-# include <linux/workqueue.h>
-#endif
-
-/*
- *
- * Work queues and delayed work queues.
- *
- * Prior to 2.5.41, the notion of work queues did not exist. Taskqueues are
- * used for work queues and timers are used for delayed work queues.
- *
- * After 2.6.20, normal work structs ("work_struct") and delayed work
- * ("delayed_work") structs were separated so that the work_struct could be
- * slimmed down. The interface was also changed such that the address of the
- * work_struct itself is passed in as the argument to the work function. This
- * requires that one embed the work struct in the larger struct containing the
- * information necessary to complete the work and use container_of() to obtain
- * the address of the containing structure.
- *
- * Users of these macros should embed a compat_work or compat_delayed_work in
- * a larger structure, then specify the larger structure as the _data argument
- * for the initialization functions, specify the work function to take
- * a compat_work_arg or compat_delayed_work_arg, then use the appropriate
- * _GET_DATA macro to obtain the reference to the structure passed in as _data.
- * An example is below.
- *
- *
- * typedef struct WorkData {
- * int data;
- * compat_work work;
- * } WorkData;
- *
- *
- * void
- * WorkFunc(compat_work_arg data)
- * {
- * WorkData *workData = COMPAT_WORK_GET_DATA(data, WorkData, work);
- *
- * ...
- * }
- *
- *
- * {
- * WorkData *workData = kmalloc(sizeof *workData, GFP_EXAMPLE);
- * if (!workData) {
- * return -ENOMEM;
- * }
- *
- * COMPAT_INIT_WORK(&workData->work, WorkFunc, workData);
- * compat_schedule_work(&workData->work);
- * }
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 41) /* { */
-typedef struct tq_struct compat_work;
-typedef struct compat_delayed_work {
- struct tq_struct work;
- struct timer_list timer;
-} compat_delayed_work;
-typedef void * compat_work_arg;
-typedef void * compat_delayed_work_arg;
-
-/*
- * Delayed work queues need to run at some point in the future in process
- * context, but task queues don't support delaying the task one is scheduling.
- * Timers allow us to delay the execution of our work queue until the future,
- * but timer handlers run in bottom-half context. As such, we use both a timer
- * and task queue and use the timer handler below to schedule the task in
- * process context immediately. The timer lets us delay execution, and the
- * task queue lets us run in process context.
- *
- * Note that this is similar to how delayed_work is implemented with work
- * queues in later kernel versions.
- */
-static inline void
-__compat_delayed_work_timer(unsigned long arg)
-{
- compat_delayed_work *dwork = (compat_delayed_work *)arg;
- if (dwork) {
- schedule_task(&dwork->work);
- }
-}
-
-# define COMPAT_INIT_WORK(_work, _func, _data) \
- INIT_LIST_HEAD(&(_work)->list); \
- (_work)->sync = 0; \
- (_work)->routine = _func; \
- (_work)->data = _data
-# define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \
- COMPAT_INIT_WORK(&(_work)->work, _func, _data); \
- init_timer(&(_work)->timer); \
- (_work)->timer.expires = 0; \
- (_work)->timer.function = __compat_delayed_work_timer; \
- (_work)->timer.data = (unsigned long)_work
-# define compat_schedule_work(_work) \
- schedule_task(_work)
-# define compat_schedule_delayed_work(_work, _delay) \
- (_work)->timer.expires = jiffies + _delay; \
- add_timer(&(_work)->timer)
-# define COMPAT_WORK_GET_DATA(_p, _type) \
- (_type *)(_p)
-# define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \
- (_type *)(_p)
-
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) /* } { */
-typedef struct work_struct compat_work;
-typedef struct work_struct compat_delayed_work;
-typedef void * compat_work_arg;
-typedef void * compat_delayed_work_arg;
-# define COMPAT_INIT_WORK(_work, _func, _data) \
- INIT_WORK(_work, _func, _data)
-# define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \
- INIT_WORK(_work, _func, _data)
-# define compat_schedule_work(_work) \
- schedule_work(_work)
-# define compat_schedule_delayed_work(_work, _delay) \
- schedule_delayed_work(_work, _delay)
-# define COMPAT_WORK_GET_DATA(_p, _type) \
- (_type *)(_p)
-# define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \
- (_type *)(_p)
-
-#else /* } Linux >= 2.6.20 { */
-typedef struct work_struct compat_work;
-typedef struct delayed_work compat_delayed_work;
-typedef struct work_struct * compat_work_arg;
-typedef struct work_struct * compat_delayed_work_arg;
-# define COMPAT_INIT_WORK(_work, _func, _data) \
- INIT_WORK(_work, _func)
-# define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \
- INIT_DELAYED_WORK(_work, _func)
-# define compat_schedule_work(_work) \
- schedule_work(_work)
-# define compat_schedule_delayed_work(_work, _delay) \
- schedule_delayed_work(_work, _delay)
-# define COMPAT_WORK_GET_DATA(_p, _type) \
- container_of(_p, _type, work)
-# define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \
- container_of(_p, _type, _member.work)
-#endif /* } */
-
-#endif /* __COMPAT_WORKQUEUE_H__ */
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * includeCheck.h --
- *
- * Restrict include file use.
- *
- * In every .h file, define one or more of these
- *
- * INCLUDE_ALLOW_VMX
- * INCLUDE_ALLOW_USERLEVEL
- * INCLUDE_ALLOW_VMMEXT
- * INCLUDE_ALLOW_VMCORE
- * INCLUDE_ALLOW_MODULE
- * INCLUDE_ALLOW_VMNIXMOD
- * INCLUDE_ALLOW_VMKERNEL
- * INCLUDE_ALLOW_DISTRIBUTE
- * INCLUDE_ALLOW_VMK_MODULE
- * INCLUDE_ALLOW_VMKDRIVERS
- * INCLUDE_ALLOW_VMIROM
- *
- * Then include this file.
- *
- * Any file that has INCLUDE_ALLOW_DISTRIBUTE defined will potentially
- * be distributed in source form along with GPLed code. Ensure
- * that this is acceptable.
- */
-
-
-/*
- * Declare a VMCORE-only variable to help classify object
- * files. The variable goes in the common block and does
- * not create multiple definition link-time conflicts.
- */
-
-#if defined VMCORE && defined VMX86_DEVEL && defined VMX86_DEBUG && \
- defined linux && !defined MODULE && \
- !defined COMPILED_WITH_VMCORE
-#define COMPILED_WITH_VMCORE compiled_with_vmcore
-#ifdef ASM
- .comm compiled_with_vmcore, 0
-#else
- asm(".comm compiled_with_vmcore, 0");
-#endif /* ASM */
-#endif
-
-
-#if defined VMCORE && \
- !(defined VMX86_VMX || defined VMM || \
- defined MONITOR_APP || defined VMMON)
-#error "Makefile problem: VMCORE without VMX86_VMX or \
- VMM or MONITOR_APP or MODULE."
-#endif
-
-#if defined VMCORE && !defined INCLUDE_ALLOW_VMCORE
-#error "The surrounding include file is not allowed in vmcore."
-#endif
-#undef INCLUDE_ALLOW_VMCORE
-
-#if defined VMX86_VMX && !defined VMCORE && \
- !(defined INCLUDE_ALLOW_VMX || defined INCLUDE_ALLOW_USERLEVEL)
-#error "The surrounding include file is not allowed in the VMX."
-#endif
-#undef INCLUDE_ALLOW_VMX
-
-#if defined USERLEVEL && !defined VMX86_VMX && !defined VMCORE && \
- !defined INCLUDE_ALLOW_USERLEVEL
-#error "The surrounding include file is not allowed at userlevel."
-#endif
-#undef INCLUDE_ALLOW_USERLEVEL
-
-#if defined VMM && !defined VMCORE && \
- !defined INCLUDE_ALLOW_VMMEXT
-#error "The surrounding include file is not allowed in the monitor."
-#endif
-#undef INCLUDE_ALLOW_VMMEXT
-
-#if defined MODULE && !defined VMKERNEL_MODULE && !defined VMNIXMOD && \
- !defined VMMON && !defined INCLUDE_ALLOW_MODULE
-#error "The surrounding include file is not allowed in driver modules."
-#endif
-#undef INCLUDE_ALLOW_MODULE
-
-#if defined VMMON && !defined INCLUDE_ALLOW_VMMON
-#error "The surrounding include file is not allowed in vmmon."
-#endif
-#undef INCLUDE_ALLOW_VMMON
-
-#if defined VMKERNEL && !defined INCLUDE_ALLOW_VMKERNEL
-#error "The surrounding include file is not allowed in the vmkernel."
-#endif
-#undef INCLUDE_ALLOW_VMKERNEL
-
-#if defined GPLED_CODE && !defined INCLUDE_ALLOW_DISTRIBUTE
-#error "The surrounding include file is not allowed in GPL code."
-#endif
-#undef INCLUDE_ALLOW_DISTRIBUTE
-
-#if defined VMKERNEL_MODULE && !defined VMKERNEL && \
- !defined INCLUDE_ALLOW_VMK_MODULE && !defined INCLUDE_ALLOW_VMKDRIVERS
-#error "The surrounding include file is not allowed in vmkernel modules."
-#endif
-#undef INCLUDE_ALLOW_VMK_MODULE
-#undef INCLUDE_ALLOW_VMKDRIVERS
-
-#if defined VMNIXMOD && !defined INCLUDE_ALLOW_VMNIXMOD
-#ifndef VMNIXMOD_VM
-#error "The surrounding include file is not allowed in vmnixmod."
-#endif
-#endif
-#undef INCLUDE_ALLOW_VMNIXMOD
-
-#if defined VMIROM && ! defined INCLUDE_ALLOW_VMIROM
-#error "The surrounding include file is not allowed in vmirom."
-#endif
-#undef INCLUDE_ALLOW_VMIROM
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- *
- * vm_basic_types.h --
- *
- * basic data types.
- */
-
-
-#ifndef _VM_BASIC_TYPES_H_
-#define _VM_BASIC_TYPES_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-/* STRICT ANSI means the Xserver build and X defines Bool differently. */
-#if !defined(__STRICT_ANSI__) || defined(__FreeBSD__)
-typedef char Bool;
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define IsBool(x) (((x) & ~1) == 0)
-#define IsBool2(x, y) ((((x) | (y)) & ~1) == 0)
-
-/*
- * Macros __i386__ and __ia64 are intrinsically defined by GCC
- */
-#ifdef __i386__
-#define VM_I386
-#endif
-
-#ifdef _WIN64
-#define __x86_64__
-#endif
-
-#ifdef __x86_64__
-#define VM_X86_64
-#define VM_I386
-#define vm_x86_64 (1)
-#else
-#define vm_x86_64 (0)
-#endif
-
-
-
-#ifdef _WIN32
-/* safe assumption for a while */
-#define VM_I386
-#endif
-
-#ifdef _MSC_VER
-
-#pragma warning (3 :4505) // unreferenced local function
-#pragma warning (disable :4018) // signed/unsigned mismatch
-#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
-#pragma warning (disable :4305) // truncation from 'const int' to 'short'
-#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
-#pragma warning (disable :4267) // truncation of 'size_t'
-#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
-#pragma warning (disable :4142) // benign redefinition of type
-
-#endif
-
-#if defined(__APPLE__) || defined(HAVE_STDINT_H)
-
-/*
- * TODO: This is a C99 standard header. We should be able to test for
- * #if __STDC_VERSION__ >= 199901L, but that breaks the Netware build
- * (which doesn't have stdint.h).
- */
-
-#include <stdint.h>
-
-typedef uint64_t uint64;
-typedef int64_t int64;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint8_t uint8;
-
-/*
- * XXX: int8_t is defined to be 'signed char' on Mac hosts.
- *
- * Unfortunately, GCC 4.0.1 warns when doing pointer assignment or
- * comparison between signed char * and char * (even if char is
- * signed).
- *
- * If we want to use int8_t to define int8, we need to go through and
- * replace uses of char * with signed char * to prevent warnings.
- */
-typedef char int8;
-
-#else /* !HAVE_STDINT_H */
-
-#ifdef _MSC_VER
-
-typedef unsigned __int64 uint64;
-typedef signed __int64 int64;
-
-#elif __GNUC__
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-#if defined(VM_X86_64)
-typedef unsigned long uint64;
-typedef long int64;
-#else
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#elif __FreeBSD__
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#else
-#error - Need compiler define for int64/uint64
-#endif /* _MSC_VER */
-
-typedef unsigned int uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
-typedef int int32;
-typedef short int16;
-typedef char int8;
-
-#endif /* HAVE_STDINT_H */
-
-/*
- * FreeBSD (for the tools build) unconditionally defines these in
- * sys/inttypes.h so don't redefine them if this file has already
- * been included. [greg]
- *
- * This applies to Solaris as well.
- */
-
-/*
- * Before trying to do the includes based on OS defines, see if we can use
- * feature-based defines to get as much functionality as possible
- */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_INTTYPES_H
-#include <sys/inttypes.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
-#endif
-
-#if !defined(USING_AUTOCONF)
-# if defined(__FreeBSD__) || defined(sun)
-# ifdef KLD_MODULE
-# include <sys/types.h>
-# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
-# include <sys/types.h>
-# else
-# include <sys/inttypes.h>
-# endif
-# endif
-# elif defined __APPLE__
-# if KERNEL
-# include <sys/unistd.h>
-# include <sys/types.h> /* mostly for size_t */
-# include <stdint.h>
-# else
-# include <unistd.h>
-# include <inttypes.h>
-# include <stdlib.h>
-# include <stdint.h>
-# endif
-# else
-# if !defined(__intptr_t_defined) && !defined(intptr_t)
-# define __intptr_t_defined
-# define intptr_t intptr_t
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef int64 intptr_t;
-# else
-typedef int32 intptr_t;
-# endif
-# endif
-# endif
-
-# ifndef _STDINT_H
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef uint64 uintptr_t;
-# else
-typedef uint32 uintptr_t;
-# endif
-# endif
-# endif
-# endif
-#endif
-
-
-/*
- * Time
- * XXX These should be cleaned up. -- edward
- */
-
-typedef int64 VmTimeType; /* Time in microseconds */
-typedef int64 VmTimeRealClock; /* Real clock kept in microseconds */
-typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */
-
-/*
- * Printf format specifiers for size_t and 64-bit number.
- * Use them like this:
- * printf("%"FMT64"d\n", big);
- *
- * FMTH is for handles/fds.
- */
-
-#ifdef _MSC_VER
- #define FMT64 "I64"
- #ifdef VM_X86_64
- #define FMTSZ "I64"
- #define FMTPD "I64"
- #define FMTH "I64"
- #else
- #define FMTSZ "I"
- #define FMTPD "I"
- #define FMTH "I"
- #endif
-#elif defined __APPLE__
- /* Mac OS hosts use the same formatters for 32- and 64-bit. */
- #define FMT64 "ll"
- #define FMTSZ "z"
- #define FMTPD "l"
- #define FMTH ""
-#elif __GNUC__
- #define FMTH ""
- #if defined(N_PLAT_NLM) || defined(sun) || \
- (defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) < 5))
- /*
- * Why (__FreeBSD__ + 0)? See bug 141008.
- * Yes, we really need to test both (__FreeBSD__ + 0) and
- * ((__FreeBSD__ + 0) < 5). No, we can't remove "+ 0" from
- * ((__FreeBSD__ + 0) < 5).
- */
- #ifdef VM_X86_64
- #define FMTSZ "l"
- #define FMTPD "l"
- #else
- #define FMTSZ ""
- #define FMTPD ""
- #endif
- #elif defined(__linux__) \
- || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
- || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
- || (defined(_POSIX2_VERSION) && _POSIX2_VERSION >= 200112L)
- /* BSD, Linux */
- #define FMTSZ "z"
-
- #if defined(VM_X86_64)
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #else
- /* Systems with a pre-C99 libc */
- #define FMTSZ "Z"
- #ifdef VM_X86_64
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #endif
- #ifdef VM_X86_64
- #define FMT64 "l"
- #elif defined(sun) || defined(__FreeBSD__)
- #define FMT64 "ll"
- #else
- #define FMT64 "L"
- #endif
-#else
- #error - Need compiler define for FMT64 and FMTSZ
-#endif
-
-/*
- * Suffix for 64-bit constants. Use it like this:
- * CONST64(0x7fffffffffffffff) for signed or
- * CONST64U(0x7fffffffffffffff) for unsigned.
- *
- * 2004.08.30(thutt):
- * The vmcore/asm64/gen* programs are compiled as 32-bit
- * applications, but must handle 64 bit constants. If the
- * 64-bit-constant defining macros are already defined, the
- * definition will not be overwritten.
- */
-
-#if !defined(CONST64) || !defined(CONST64U)
-#ifdef _MSC_VER
-#define CONST64(c) c##I64
-#define CONST64U(c) c##uI64
-#elif defined __APPLE__
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#elif __GNUC__
-#ifdef VM_X86_64
-#define CONST64(c) c##L
-#define CONST64U(c) c##uL
-#else
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#endif
-#else
-#error - Need compiler define for CONST64
-#endif
-#endif
-
-/*
- * Use CONST3264/CONST3264U if you want a constant to be
- * treated as a 32-bit number on 32-bit compiles and
- * a 64-bit number on 64-bit compiles. Useful in the case
- * of shifts, like (CONST3264U(1) << x), where x could be
- * more than 31 on a 64-bit compile.
- */
-
-#ifdef VM_X86_64
- #define CONST3264(a) CONST64(a)
- #define CONST3264U(a) CONST64U(a)
-#else
- #define CONST3264(a) (a)
- #define CONST3264U(a) (a)
-#endif
-
-#define MIN_INT32 ((int32)0x80000000)
-#define MAX_INT32 ((int32)0x7fffffff)
-
-#define MIN_UINT32 ((uint32)0)
-#define MAX_UINT32 ((uint32)0xffffffff)
-
-#define MIN_INT64 (CONST64(0x8000000000000000))
-#define MAX_INT64 (CONST64(0x7fffffffffffffff))
-
-#define MIN_UINT64 (CONST64U(0))
-#define MAX_UINT64 (CONST64U(0xffffffffffffffff))
-
-typedef uint8 *TCA; /* Pointer into TC (usually). */
-
-/*
- * Type big enough to hold an integer between 0..100
- */
-typedef uint8 Percent;
-#define AsPercent(v) ((Percent)(v))
-#define CHOOSE_PERCENT AsPercent(101)
-
-
-typedef uintptr_t VA;
-typedef uintptr_t VPN;
-
-typedef uint64 PA;
-typedef uint32 PPN;
-
-typedef uint64 PhysMemOff;
-typedef uint64 PhysMemSize;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 BA;
-#endif
-typedef uint32 BPN;
-typedef uint32 PageNum;
-typedef unsigned MemHandle;
-typedef int32 World_ID;
-
-#define INVALID_WORLD_ID ((World_ID)-1)
-
-typedef World_ID User_CartelID;
-#define INVALID_CARTEL_ID INVALID_WORLD_ID
-
-typedef User_CartelID User_SessionID;
-#define INVALID_SESSION_ID INVALID_CARTEL_ID
-
-typedef User_CartelID User_CartelGroupID;
-#define INVALID_CARTELGROUP_ID INVALID_CARTEL_ID
-
-typedef uint32 Worldlet_ID;
-#define INVALID_WORLDLET_ID ((Worldlet_ID)-1)
-
-/* world page number */
-typedef uint32 WPN;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 MA;
-typedef uint32 MPN;
-#endif
-
-/*
- * This type should be used for variables that contain sector
- * position/quantity.
- */
-typedef uint64 SectorType;
-
-/*
- * Linear address
- */
-
-typedef uintptr_t LA;
-typedef uintptr_t LPN;
-#define LA_2_LPN(_la) ((_la) >> PAGE_SHIFT)
-#define LPN_2_LA(_lpn) ((_lpn) << PAGE_SHIFT)
-
-#define LAST_LPN ((((LA) 1) << (8 * sizeof(LA) - PAGE_SHIFT)) - 1)
-#define LAST_LPN32 ((((LA32)1) << (8 * sizeof(LA32) - PAGE_SHIFT)) - 1)
-#define LAST_LPN64 ((((LA64)1) << (8 * sizeof(LA64) - PAGE_SHIFT)) - 1)
-
-/* Valid bits in a LPN. */
-#define LPN_MASK LAST_LPN
-#define LPN_MASK32 LAST_LPN32
-#define LPN_MASK64 LAST_LPN64
-
-/*
- * On 64 bit platform, address and page number types default
- * to 64 bit. When we need to represent a 32 bit address, we use
- * types defined below.
- *
- * On 32 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint32 VA32;
-typedef uint32 VPN32;
-typedef uint32 LA32;
-typedef uint32 LPN32;
-typedef uint32 PA32;
-typedef uint32 PPN32;
-typedef uint32 MA32;
-typedef uint32 MPN32;
-
-/*
- * On 64 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint64 VA64;
-typedef uint64 VPN64;
-typedef uint64 LA64;
-typedef uint64 LPN64;
-typedef uint64 PA64;
-typedef uint64 PPN64;
-typedef uint64 MA64;
-typedef uint64 MPN64;
-
-/*
- * VA typedefs for user world apps.
- */
-typedef VA32 UserVA32;
-typedef VA64 UserVA64;
-typedef UserVA64 UserVAConst; /* Userspace ptr to data that we may only read. */
-typedef UserVA32 UserVA32Const; /* Userspace ptr to data that we may only read. */
-typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */
-#ifdef VMKERNEL
-typedef UserVA64 UserVA;
-#else
-typedef void * UserVA;
-#endif
-
-
-/*
- * Maximal possible PPN value (errors too) that PhysMem can handle.
- * Must be at least as large as MAX_PPN which is the maximum PPN
- * for any region other than buserror.
- */
-#define PHYSMEM_MAX_PPN ((PPN)0xffffffff)
-#define MAX_PPN ((PPN)0x1fffffff) /* Maximal observable PPN value. */
-#define INVALID_PPN ((PPN)0xffffffff)
-
-#define INVALID_BPN ((BPN) 0x1fffffff)
-
-#define INVALID_MPN ((MPN)-1)
-#define MEMREF_MPN ((MPN)-2)
-#define RESERVED_MPN ((MPN) 0)
-/* Support 43 bits of address space. */
-#define MAX_MPN ((MPN)0x7fffffff)
-
-#define INVALID_LPN ((LPN)-1)
-#define INVALID_VPN ((VPN)-1)
-#define INVALID_LPN64 ((LPN64)-1)
-#define INVALID_PAGENUM ((PageNum)-1)
-#define INVALID_WPN ((WPN) -1)
-
-
-/*
- * Format modifier for printing VA, LA, and VPN.
- * Use them like this: Log("%#"FMTLA"x\n", laddr)
- */
-
-#if defined(VMM64) || defined(FROBOS64) || vm_x86_64 || defined __APPLE__
-# define FMTLA "l"
-# define FMTVA "l"
-# define FMTVPN "l"
-#else
-# define FMTLA ""
-# define FMTVA ""
-# define FMTVPN ""
-#endif
-
-#ifndef EXTERN
-#define EXTERN extern
-#endif
-#define CONST const
-
-
-#ifndef INLINE
-# ifdef _MSC_VER
-# define INLINE __inline
-# else
-# define INLINE inline
-# endif
-#endif
-
-
-/*
- * Annotation for data that may be exported into a DLL and used by other
- * apps that load that DLL and import the data.
- */
-#if defined(_WIN32) && defined(VMX86_IMPORT_DLLDATA)
-# define VMX86_EXTERN_DATA extern __declspec(dllimport)
-#else // !_WIN32
-# define VMX86_EXTERN_DATA extern
-#endif
-
-#if defined(_WIN32) && !defined(VMX86_NO_THREADS)
-#define THREADSPECIFIC __declspec(thread)
-#else
-#define THREADSPECIFIC
-#endif
-
-/*
- * Due to the wonderful "registry redirection" feature introduced in
- * 64-bit Windows, if you access any key under HKLM\Software in 64-bit
- * code, you need to open/create/delete that key with
- * VMKEY_WOW64_32KEY if you want a consistent view with 32-bit code.
- */
-
-#ifdef _WIN32
-#ifdef _WIN64
-#define VMW_KEY_WOW64_32KEY KEY_WOW64_32KEY
-#else
-#define VMW_KEY_WOW64_32KEY 0x0
-#endif
-#endif
-
-
-/*
- * Consider the following reasons functions are inlined:
- *
- * 1) inlined for performance reasons
- * 2) inlined because it's a single-use function
- *
- * Functions which meet only condition 2 should be marked with this
- * inline macro; It is not critical to be inlined (but there is a
- * code-space & runtime savings by doing so), so when other callers
- * are added the inline-ness should be removed.
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-/*
- * Starting at version 3.3, gcc does not always inline functions marked
- * 'inline' (it depends on their size). To force gcc to do so, one must use the
- * extra __always_inline__ attribute.
- */
-# define INLINE_SINGLE_CALLER INLINE __attribute__((__always_inline__))
-# if defined(VMM) \
- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
-# warning Verify INLINE_SINGLE_CALLER '__always_inline__' attribute (did \
- monitor size change?)
-# endif
-#else
-# define INLINE_SINGLE_CALLER INLINE
-#endif
-
-/*
- * Used when a hard guaranteed of no inlining is needed. Very few
- * instances need this since the absence of INLINE is a good hint
- * that gcc will not do inlining.
- */
-
-#if defined(__GNUC__) && defined(VMM)
-#define ABSOLUTELY_NOINLINE __attribute__((__noinline__))
-#endif
-
-/*
- * Attributes placed on function declarations to tell the compiler
- * that the function never returns.
- */
-
-#ifdef _MSC_VER
-#define NORETURN __declspec(noreturn)
-#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9)
-#define NORETURN __attribute__((__noreturn__))
-#else
-#define NORETURN
-#endif
-
-/*
- * GCC 3.2 inline asm needs the + constraint for input/ouput memory operands.
- * Older GCCs don't know about it --hpreg
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
-# define VM_ASM_PLUS 1
-#else
-# define VM_ASM_PLUS 0
-#endif
-
-/*
- * Branch prediction hints:
- * LIKELY(exp) - Expression exp is likely TRUE.
- * UNLIKELY(exp) - Expression exp is likely FALSE.
- * Usage example:
- * if (LIKELY(excCode == EXC_NONE)) {
- * or
- * if (UNLIKELY(REAL_MODE(vc))) {
- *
- * We know how to predict branches on gcc3 and later (hopefully),
- * all others we don't so we do nothing.
- */
-
-#if (__GNUC__ >= 3)
-/*
- * gcc3 uses __builtin_expect() to inform the compiler of an expected value.
- * We use this to inform the static branch predictor. The '!!' in LIKELY
- * will convert any !=0 to a 1.
- */
-#define LIKELY(_exp) __builtin_expect(!!(_exp), 1)
-#define UNLIKELY(_exp) __builtin_expect((_exp), 0)
-#else
-#define LIKELY(_exp) (_exp)
-#define UNLIKELY(_exp) (_exp)
-#endif
-
-/*
- * GCC's argument checking for printf-like functions
- * This is conditional until we have replaced all `"%x", void *'
- * with `"0x%08x", (uint32) void *'. Note that %p prints different things
- * on different platforms. Argument checking is enabled for the
- * vmkernel, which has already been cleansed.
- *
- * fmtPos is the position of the format string argument, beginning at 1
- * varPos is the position of the variable argument, beginning at 1
- */
-
-#if defined(__GNUC__)
-# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
-#else
-# define PRINTF_DECL(fmtPos, varPos)
-#endif
-
-#if defined(__GNUC__)
-# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
-#else
-# define SCANF_DECL(fmtPos, varPos)
-#endif
-
-/*
- * UNUSED_PARAM should surround the parameter name and type declaration,
- * e.g. "int MyFunction(int var1, UNUSED_PARAM(int var2))"
- *
- */
-
-#ifndef UNUSED_PARAM
-# if defined(__GNUC__)
-# define UNUSED_PARAM(_parm) _parm __attribute__((__unused__))
-# else
-# define UNUSED_PARAM(_parm) _parm
-# endif
-#endif
-
-/*
- * REGPARM defaults to REGPARM3, i.e., a requent that gcc
- * puts the first three arguments in registers. (It is fine
- * if the function has fewer than three args.) Gcc only.
- * Syntactically, put REGPARM where you'd put INLINE or NORETURN.
- */
-
-#if defined(__GNUC__)
-# define REGPARM0 __attribute__((regparm(0)))
-# define REGPARM1 __attribute__((regparm(1)))
-# define REGPARM2 __attribute__((regparm(2)))
-# define REGPARM3 __attribute__((regparm(3)))
-# define REGPARM REGPARM3
-#else
-# define REGPARM0
-# define REGPARM1
-# define REGPARM2
-# define REGPARM3
-# define REGPARM
-#endif
-
-/*
- * ALIGNED specifies minimum alignment in "n" bytes.
- */
-
-#ifdef __GNUC__
-#define ALIGNED(n) __attribute__((__aligned__(n)))
-#else
-#define ALIGNED(n)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_OFFSET_CHECK -- */ /**
- *
- * \brief Check if the actual offsef of a member in a structure
- * is what is expected
- *
- *
- * \param[in] STRUCT Structure the member is a part of.
- * \param[in] MEMBER Member to check the offset of.
- * \param[in] OFFSET Expected offset of MEMBER in STRUCTURE.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to OFFSET to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == (OFFSET + DEBUG_EXTRA))
-#else
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == OFFSET)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_SIZE_CHECK -- */ /**
- *
- * \brief Check if the actual size of a structure is what is expected
- *
- *
- * \param[in] STRUCT Structure whose size is to be checked.
- * \param[in] SIZE Expected size of STRUCT.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to SIZE to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == (SIZE + DEBUG_EXTRA))
-#else
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == SIZE)
-#endif
-
-/*
- * __func__ is a stringified function name that is part of the C99 standard. The block
- * below defines __func__ on older systems where the compiler does not support that
- * macro.
- */
-#if defined(__GNUC__) \
- && ((__GNUC__ == 2 && __GNUC_MINOR < 96) \
- || (__GNUC__ < 2))
-# define __func__ __FUNCTION__
-#endif
-
-/*
- * Once upon a time, this was used to silence compiler warnings that
- * get generated when the compiler thinks that a function returns
- * when it is marked noreturn. Don't do it. Use NOT_REACHED().
- */
-
-#define INFINITE_LOOP() do { } while (1)
-
-/*
- * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_
- * is defined. Use the same logic here so we don't define it twice. [greg]
- */
-#ifdef __FreeBSD__
-# ifdef _BSD_SIZE_T_
-# undef _BSD_SIZE_T_
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# ifdef _BSD_SSIZE_T_
-# undef _BSD_SSIZE_T_
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#else
-# ifndef _SIZE_T
-# define _SIZE_T
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(ssize_t) && \
- !defined(__ssize_t_defined) && !defined(_SSIZE_T_DECLARED)
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#endif
-
-/*
- * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The pid is %"FMTPID".\n", pid);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTPID "d"
-# else
-# define FMTPID "lu"
-# endif
-#else
-# define FMTPID "d"
-#endif
-
-/*
- * Format modifier for printing uid_t. On Solaris 10 and earlier, uid_t
- * is a ulong, but on other platforms it's an unsigned int.
- * Use this like this: printf("The uid is %"FMTUID".\n", uid);
- */
-#if defined(sun) && !defined(SOL11)
-# ifdef VM_X86_64
-# define FMTUID "u"
-# else
-# define FMTUID "lu"
-# endif
-#else
-# define FMTUID "u"
-#endif
-
-/*
- * Format modifier for printing mode_t. On sun the mode_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The mode is %"FMTMODE".\n", mode);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTMODE "o"
-# else
-# define FMTMODE "lo"
-# endif
-#else
-# define FMTMODE "o"
-#endif
-
-/*
- * Format modifier for printing time_t. Most platforms define a time_t to be
- * a long int, but on FreeBSD (as of 5.0, it seems), the time_t is a signed
- * size quantity. Refer to the definition of FMTSZ to see why we need silly
- * preprocessor arithmetic.
- * Use this like this: printf("The mode is %"FMTTIME".\n", time);
- */
-#if defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) >= 5)
-# define FMTTIME FMTSZ"d"
-#else
-# define FMTTIME "ld"
-#endif
-
-/*
- * Define MXSemaHandle here so both vmmon and vmx see this definition.
- */
-
-#ifdef _WIN32
-typedef uintptr_t MXSemaHandle;
-#else
-typedef int MXSemaHandle;
-#endif
-
-/*
- * Define type for poll device handles.
- */
-
-#ifdef _WIN32
-typedef uintptr_t PollDevHandle;
-#else
-typedef int PollDevHandle;
-#endif
-
-/*
- * Define the utf16_t type.
- */
-
-#if defined(_WIN32) && defined(_NATIVE_WCHAR_T_DEFINED)
-typedef wchar_t utf16_t;
-#else
-typedef uint16 utf16_t;
-#endif
-
-#endif /* _VM_BASIC_TYPES_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef VM_DEVICE_VERSION_H
-#define VM_DEVICE_VERSION_H
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMCORE
-#include "includeCheck.h"
-
-#ifdef _WIN32
-#include "guiddef.h"
-#endif
-
-/* LSILogic 53C1030 Parallel SCSI controller
- * LSILogic SAS1068 SAS controller
- */
-#define PCI_VENDOR_ID_LSILOGIC 0x1000
-#define PCI_DEVICE_ID_LSI53C1030 0x0030
-#define PCI_DEVICE_ID_LSISAS1068 0x0054
-
-/* Our own PCI IDs
- * VMware SVGA II (Unified VGA)
- * VMware SVGA (PCI Accelerator)
- * VMware vmxnet (Idealized NIC)
- * VMware vmxscsi (Abortive idealized SCSI controller)
- * VMware chipset (Subsystem ID for our motherboards)
- * VMware e1000 (Subsystem ID)
- * VMware vmxnet3 (Uniform Pass Through NIC)
- */
-#define PCI_VENDOR_ID_VMWARE 0x15AD
-#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
-#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
-#define PCI_DEVICE_ID_VMWARE_NET 0x0720
-#define PCI_DEVICE_ID_VMWARE_SCSI 0x0730
-#define PCI_DEVICE_ID_VMWARE_VMCI 0x0740
-#define PCI_DEVICE_ID_VMWARE_CHIPSET 0x1976
-#define PCI_DEVICE_ID_VMWARE_82545EM 0x0750 /* single port */
-#define PCI_DEVICE_ID_VMWARE_82546EB 0x0760 /* dual port */
-#define PCI_DEVICE_ID_VMWARE_EHCI 0x0770
-#define PCI_DEVICE_ID_VMWARE_1394 0x0780
-#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
-#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
-#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
-#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
-
-/* The hypervisor device might grow. Please leave room
- * for 7 more subfunctions.
- */
-#define PCI_DEVICE_ID_VMWARE_HYPER 0x0800
-#define PCI_DEVICE_ID_VMWARE_VMI 0x0801
-
-#define PCI_DEVICE_VMI_CLASS 0x05
-#define PCI_DEVICE_VMI_SUBCLASS 0x80
-#define PCI_DEVICE_VMI_INTERFACE 0x00
-#define PCI_DEVICE_VMI_REVISION 0x01
-
-/* From linux/pci_ids.h:
- * AMD Lance Ethernet controller
- * BusLogic SCSI controller
- * Ensoniq ES1371 sound controller
- */
-#define PCI_VENDOR_ID_AMD 0x1022
-#define PCI_DEVICE_ID_AMD_VLANCE 0x2000
-#define PCI_VENDOR_ID_BUSLOGIC 0x104B
-#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
-#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
-#define PCI_VENDOR_ID_ENSONIQ 0x1274
-#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
-
-/* From linux/pci_ids.h:
- * Intel 82439TX (430 HX North Bridge)
- * Intel 82371AB (PIIX4 South Bridge)
- * Intel 82443BX (440 BX North Bridge and AGP Bridge)
- * Intel 82545EM (e1000, server adapter, single port)
- * Intel 82546EB (e1000, server adapter, dual port)
- * Intel ICH7_16 (High Definition Audio controller)
- * Intel HECI (as embedded in ich9m)
- */
-#define PCI_VENDOR_ID_INTEL 0x8086
-#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
-#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
-#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
-#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
-#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
-#define PCI_DEVICE_ID_INTEL_82443BX 0x7190
-#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
-#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 /* Used when no AGP support */
-#define PCI_DEVICE_ID_INTEL_82545EM 0x100f
-#define PCI_DEVICE_ID_INTEL_82546EB 0x1010
-#define PCI_DEVICE_ID_INTEL_ICH7_16 0x27d8
-#define PCI_DEVICE_ID_INTEL_HECI 0x2a74
-
-
-/************* Strings for IDE Identity Fields **************************/
-#define VIDE_ID_SERIAL_STR "00000000000000000001" /* Must be 20 Bytes */
-#define VIDE_ID_FIRMWARE_STR "00000001" /* Must be 8 Bytes */
-
-/* No longer than 40 Bytes */
-#define VIDE_ATA_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE Hard Drive"
-#define VIDE_ATAPI_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE CDROM Drive"
-
-#define ATAPI_VENDOR_ID "NECVMWar" /* Must be 8 Bytes */
-#define ATAPI_PRODUCT_ID PRODUCT_GENERIC_NAME " IDE CDROM" /* Must be 16 Bytes */
-#define ATAPI_REV_LEVEL "1.00" /* Must be 4 Bytes */
-
-#define IDE_NUM_INTERFACES 2 /* support for two interfaces */
-#define IDE_DRIVES_PER_IF 2
-
-/************* Strings for SCSI Identity Fields **************************/
-#define SCSI_DISK_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI Hard Drive"
-#define SCSI_DISK_VENDOR_NAME COMPANY_NAME
-#define SCSI_DISK_REV_LEVEL "1.0"
-#define SCSI_CDROM_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI CDROM Drive"
-#define SCSI_CDROM_VENDOR_NAME COMPANY_NAME
-#define SCSI_CDROM_REV_LEVEL "1.0"
-
-/************* SCSI implementation limits ********************************/
-#define SCSI_MAX_CONTROLLERS 4 // Need more than 1 for MSCS clustering
-#define SCSI_MAX_DEVICES 16 // BT-958 emulates only 16
-#define SCSI_IDE_CHANNEL SCSI_MAX_CONTROLLERS
-#define SCSI_IDE_HOSTED_CHANNEL (SCSI_MAX_CONTROLLERS + 1)
-#define SCSI_MAX_CHANNELS (SCSI_MAX_CONTROLLERS + 2)
-
-/************* Strings for the VESA BIOS Identity Fields *****************/
-#define VBE_OEM_STRING COMPANY_NAME " SVGA"
-#define VBE_VENDOR_NAME COMPANY_NAME
-#define VBE_PRODUCT_NAME PRODUCT_GENERIC_NAME
-
-/************* PCI implementation limits ********************************/
-#define PCI_MAX_BRIDGES 15
-
-/************* Ethernet implementation limits ***************************/
-#define MAX_ETHERNET_CARDS 10
-
-/************* PCI Passthrough implementation limits ********************/
-#define MAX_PCI_PASSTHRU_DEVICES 2
-
-/************* USB implementation limits ********************************/
-#define MAX_USB_DEVICES_PER_HOST_CONTROLLER 127
-
-/************* Strings for Host USB Driver *******************************/
-
-#ifdef _WIN32
-
-/*
- * Globally unique ID for the VMware device interface. Define INITGUID before including
- * this header file to instantiate the variable.
- */
-DEFINE_GUID(GUID_DEVICE_INTERFACE_VMWARE_USB_DEVICES,
-0x2da1fe75, 0xaab3, 0x4d2c, 0xac, 0xdf, 0x39, 0x8, 0x8c, 0xad, 0xa6, 0x65);
-
-/*
- * Globally unique ID for the VMware device setup class.
- */
-DEFINE_GUID(GUID_CLASS_VMWARE_USB_DEVICES,
-0x3b3e62a5, 0x3556, 0x4d7e, 0xad, 0xad, 0xf5, 0xfa, 0x3a, 0x71, 0x2b, 0x56);
-
-/*
- * This string defines the device ID string of a VMware USB device.
- * The format is USB\Vid_XXXX&Pid_YYYY, where XXXX and YYYY are the
- * hexadecimal representations of the vendor and product ids, respectively.
- *
- * The official vendor ID for VMware, Inc. is 0x0E0F.
- * The product id for USB generic devices is 0x0001.
- */
-#define USB_VMWARE_DEVICE_ID_WIDE L"USB\\Vid_0E0F&Pid_0001"
-#define USB_DEVICE_ID_LENGTH (sizeof(USB_VMWARE_DEVICE_ID_WIDE) / sizeof(WCHAR))
-
-#ifdef UNICODE
-#define USB_PNP_SETUP_CLASS_NAME L"VMwareUSBDevices"
-#define USB_PNP_DRIVER_NAME L"vmusb"
-#else
-#define USB_PNP_SETUP_CLASS_NAME "VMwareUSBDevices"
-#define USB_PNP_DRIVER_NAME "vmusb"
-#endif
-#endif
-
-#endif /* VM_DEVICE_VERSION_H */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_begin.h --
- *
- * Begin of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(push, 1)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_end.h --
- *
- * End of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(pop)
-#elif __GNUC__
-__attribute__((__packed__))
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __VMWARE_PACK_INIT_H__
-# define __VMWARE_PACK_INIT_H__
-
-
-/*
- * vmware_pack_init.h --
- *
- * Platform-independent code to make the compiler pack (i.e. have them
- * occupy the smallest possible space) structure definitions. The following
- * constructs are known to work --hpreg
- *
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * ;
- *
- * typedef
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * foo;
- */
-
-
-#ifdef _MSC_VER
-/*
- * MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is
- * not balanced within 1 included file. That is annoying because our scheme
- * is based on the pairing being balanced between 2 included files.
- *
- * So we disable this warning, but this is safe because the compiler will also
- * emit warning 4161 when there is more pops than pushes within 1 main
- * file --hpreg
- */
-
-# pragma warning(disable:4103)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
-
-
-#endif /* __VMWARE_PACK_INIT_H__ */
vmxnet3_do_poll(adapter, budget, &txd_done, &rxd_done);
if (rxd_done < budget) {
- compat_netif_rx_complete(adapter->netdev, napi);
+ compat_napi_complete(adapter->netdev, napi);
vmxnet3_enable_intr(adapter, 0);
}
return rxd_done;
poll_dev->quota -= rxd_done;
if (rxd_done < quota) {
- netif_rx_complete(poll_dev);
+ compat_napi_complete(poll_dev, unused);
vmxnet3_enable_intr(adapter, 0);
return 0;
}
vmxnet3_disable_intr(adapter, 0);
}
- compat_netif_rx_schedule(dev, &adapter->napi);
+ compat_napi_schedule(dev, &adapter->napi);
#else
vmxnet3_tq_tx_complete(&adapter->tx_queue, adapter);
#define VMXNET3_REG_ICR 0x38 /* Interrupt Cause Register */
#define VMXNET3_REG_ECR 0x40 /* Event Cause Register */
+#define VMXNET3_REG_WSAL 0xF00 /* Wireless Shared Address Lo */
+#define VMXNET3_REG_WSAH 0xF08 /* Wireless Shared Address Hi */
+#define VMXNET3_REG_WCMD 0xF18 /* Wireless Command */
+
/* BAR 0 */
#define VMXNET3_REG_IMR 0x0 /* Interrupt Mask Register */
#define VMXNET3_REG_TXPROD 0x600 /* Tx Producer Index */
#define VMXNET3_LINK_UP (10000 << 16 | 1) // 10 Gbps, up
#define VMXNET3_LINK_DOWN 0
+
+#define VMXWIFI_DRIVER_SHARED_LEN 8192
+
#endif /* _VMXNET3_DEFS_H_ */
####
SRCROOT = .
+#
+# open-vm-tools doesn't replicate shared source files for different modules;
+# instead, files are kept in shared locations. So define a few useful macros
+# to be able to handle both cases cleanly.
+#
+INCLUDE :=
+ifdef OVT_SOURCE_DIR
+AUTOCONF_DIR := $(OVT_SOURCE_DIR)/modules/linux/shared/autoconf
+VMLIB_PATH = $(OVT_SOURCE_DIR)/lib/$(1)
+INCLUDE += -I$(OVT_SOURCE_DIR)/modules/linux/shared
+INCLUDE += -I$(OVT_SOURCE_DIR)/lib/include
+else
+AUTOCONF_DIR := $(SRCROOT)/shared/autoconf
+INCLUDE += -I$(SRCROOT)/shared
+endif
+
+
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
vm_product_defines = $(if $(findstring tools,$(1)), -DVMX86_TOOLS,)
CC_OPTS += $(call vm_product_defines, $(PRODUCT))
-INCLUDE := -I.
-INCLUDE := -I$(SRCROOT)/include
+INCLUDE += -I.
+INCLUDE += -I$(SRCROOT)/include
INCLUDE += -I$(SRCROOT)/linux
INCLUDE += -I$(SRCROOT)/common
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
# This test is inverted.
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/sk_filter.c,, -DVMW_HAVE_NEW_SKFILTER )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/sk_filter.c,, -DVMW_HAVE_NEW_SKFILTER )
T := /tmp
MODPOST_VMCI_SYMVERS := $(wildcard $(T)/VMwareVMCIModule.symvers)
$(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, $(wildcard $(SRCROOT)/linux/*.c)))
+#
+# In open-vm-tools, need to compile the common sources from the shared directory.
+#
+DRIVERLOG := driverLog.o
+$(DRIVER)-y += $(DRIVERLOG)
+
+VSOCK_PATH := $(shell cd $(SRCROOT) && pwd)
+ifdef OVT_SOURCE_DIR
+DRIVERLOG_PATH := $(OVT_SOURCE_DIR)/modules/linux/shared
+else
+DRIVERLOG_PATH := $(VSOCK_PATH)/shared
+endif
+
+$(addprefix $(VSOCK_PATH)/,$(DRIVERLOG)): $(VSOCK_PATH)/%.o: $(DRIVERLOG_PATH)/%.c
+ $(Q)$(rule_cc_o_c)
+
clean:
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \
Module.symvers Modules.symvers Module.markers modules.order \
CC_OPTS := -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS)
-INCLUDE := -I$(SRCROOT)/include
+INCLUDE += -I$(SRCROOT)/include
INCLUDE += -I$(SRCROOT)/linux
INCLUDE += -I$(SRCROOT)/common
INCLUDE += -I$(HEADER_DIR)
-INCLUDE += $(shell $(CC) $(INCLUDE) -E $(SRCROOT)/autoconf/geninclude.c \
+INCLUDE += $(shell $(CC) $(INCLUDE) -E $(AUTOCONF_DIR)/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/skas1.c, -DVMW_SKAS_MMAP, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/epoll.c, -DVMW_HAVE_EPOLL, )
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/skas1.c, -DVMW_SKAS_MMAP, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/epoll.c, -DVMW_HAVE_EPOLL, )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
# This test is inverted.
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/sk_filter.c,, -DVMW_HAVE_NEW_SKFILTER )
+CC_OPTS += $(call vm_check_build, $(AUTOCONF_DIR)/sk_filter.c,, -DVMW_HAVE_NEW_SKFILTER )
CC_OPTS += -DVMW_KMEMCR_HAS_DTOR
LINUX_DEPS := ${LINUX_OBJS:.o=.d}
OBJS := $(LINUX_OBJS)
+ifdef OVT_SOURCE_PATH
+driverLog.o: $(OVT_SOURCE_DIR)/modules/linux/shared/driverLog.c
+ $(CC) $(CC_OPTS) $(INCLUDE) -c $<
+else
+driverLog.o: shared/driverLog.c
+ $(CC) $(CC_OPTS) $(INCLUDE) -c $<
+endif
+
####
#### Make Targets are beneath here.
####
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-/*
- * All kernels before 2.6.22 take 6 arguments. All kernels since
- * 2.6.23-rc1 take 5 arguments. Only kernels between 2.6.22 and
- * 2.6.23-rc1 are questionable - we could ignore them if we wanted,
- * nobody cares about them even now. But unfortunately RedHat is
- * re-releasing 2.6.X-rc kernels under 2.6.(X-1) name, so they
- * are releasing 2.6.23-rc1 as 2.6.22-5055-something, so we have
- * to do autodetection for them.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
-/* Success... */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#error "This test intentionally fails on 2.6.23 and newer kernels."
-#else
-#include <linux/slab.h>
-
-struct kmem_cache *kmemtest(void) {
- return kmem_cache_create("test", 12, 0, 0, NULL, NULL);
-}
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Detect whether we have 'struct poll_wqueues'
- * 2.6.x kernels always had this struct. Stock 2.4.x kernels
- * never had it, but some distros backported epoll patch.
- */
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-#include <linux/poll.h>
-
-void poll_test(void) {
- struct poll_wqueues test;
-
- return poll_initwait(&test);
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
-#include <linux/fs.h>
-#include <linux/types.h> /* loff_t */
-#include <linux/stddef.h> /* NULL */
-
-/*
- * After 2.6.18, filldir and statfs were changed to send 64-bit inode
- * numbers to user space. Red Hat backported this behavior into a 2.6.17
- * kernel.
- *
- * This test will fail on a kernel with such a patch.
- */
-static int LinuxDriverFilldir(void *buf,
- const char *name,
- int namelen,
- loff_t offset,
- ino_t ino,
- unsigned int d_type)
-{
- return 0;
-}
-
-void test(void)
-{
- vfs_readdir(NULL, LinuxDriverFilldir, NULL);
-}
-#else
-#error "This test intentionally fails on 2.6.20 and newer kernels."
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-
-#ifdef CONFIG_X86_VOYAGER
-APATH/mach-voyager
-#endif
-#ifdef CONFIG_X86_VISWS
-APATH/mach-visws
-#endif
-#ifdef CONFIG_X86_NUMAQ
-APATH/mach-numaq
-#endif
-#ifdef CONFIG_X86_BIGSMP
-APATH/mach-bigsmp
-#endif
-#ifdef CONFIG_X86_SUMMIT
-APATH/mach-summit
-#endif
-#ifdef CONFIG_X86_GENERICARCH
-APATH/mach-generic
-#endif
-APATH/mach-default
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-
-#include <linux/fs.h>
-
-/*
- * Around 2.6.18, a pointer to a vfsmount was added to get_sb. Red Hat
- * backported this behavior into a 2.6.17 kernel.
- *
- * This test will fail on a kernel with such a patch.
- */
-static struct super_block * LinuxDriverGetSb(struct file_system_type *fs_type,
- int flags,
- const char *dev_name,
- void *rawData)
-{
- return 0;
-}
-
-struct file_system_type fs_type = {
- .get_sb = LinuxDriverGetSb
-};
-#else
-#error "This test intentionally fails on 2.6.19 or newer kernels."
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * set_user_nice appeared in 2.4.21. But some distros
- * backported it to older kernels.
- */
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 21)
-#include <linux/sched.h>
-
-void test(void) {
- set_user_nice(current, -20);
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * SKAS patch adds 'struct mm *mm' as first argument to do_mmap_pgoff.
- * This patch never hit mainstream kernel.
- */
-
-#include <linux/mm.h>
-
-unsigned long check_do_mmap_pgoff(struct mm_struct *mm, struct file *file,
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flag,
- unsigned long pgoff) {
- return do_mmap_pgoff(mm, file, addr, len, prot, flag, pgoff);
-}
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#include <linux/autoconf.h>
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include <linux/fs.h>
-
-/*
- * Around 2.6.18, the super_block pointer in statfs was changed to a dentry
- * pointer. Red Hat backported this behavior into a 2.6.17 kernel.
- *
- * This test will fail on a kernel with such a patch.
- */
-static int LinuxDriverStatFs(struct super_block *sb,
- struct kstatfs *stat)
-{
- return 0;
-}
-
-struct super_operations super_ops = {
- .statfs = LinuxDriverStatFs
-};
-#else
-#error "This test intentionally fails on 2.6.19 and newer kernels."
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_COMPLETION_H__
-# define __COMPAT_COMPLETION_H__
-
-/*
- * The kernel's completion objects were made available for module use in 2.4.9.
- *
- * Between 2.4.0 and 2.4.9, we implement completions on our own using
- * waitqueues and counters. This was done so that we could safely support
- * functions like complete_all(), which cannot be implemented using semaphores.
- *
- * Prior to that, the waitqueue API is substantially different, and since none
- * of our modules that are built against older kernels need complete_all(),
- * we fallback on a simple semaphore-based implementation.
- */
-
-/*
- * Native completions.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#include <linux/completion.h>
-#define compat_completion struct completion
-#define compat_init_completion(comp) init_completion(comp)
-#define COMPAT_DECLARE_COMPLETION DECLARE_COMPLETION
-#define compat_wait_for_completion(comp) wait_for_completion(comp)
-#define compat_complete(comp) complete(comp)
-
-/* complete_all() was exported in 2.6.6. */
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
-# include "compat_wait.h"
-# include "compat_list.h"
-# include "compat_spinlock.h"
-# include "compat_sched.h"
-# define compat_complete_all(x) \
- ({ \
- struct list_head *currLinks; \
- spin_lock(&(x)->wait.lock); \
- (x)->done += UINT_MAX/2; \
- \
- list_for_each(currLinks, &(x)->wait.task_list) { \
- wait_queue_t *currQueue = list_entry(currLinks, wait_queue_t, task_list); \
- wake_up_process(currQueue->task); \
- } \
- spin_unlock(&(x)->wait.lock); \
- })
-# else
-# define compat_complete_all complete_all
-# endif
-
-/*
- * Completions via waitqueues.
- */
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-
-/*
- * Kernel completions in 2.4.9 and beyond use a counter and a waitqueue, and
- * our implementation is quite similar. Because __wake_up_common() is not
- * exported, our implementations of compat_complete() and compat_complete_all()
- * are somewhat racy: the counter is incremented outside of the waitqueue's
- * lock.
- *
- * As a result, our completion cannot guarantee in-order wake ups. For example,
- * suppose thread A is entering compat_complete(), thread B is sleeping inside
- * compat_wait_for_completion(), and thread C is just now entering
- * compat_wait_for_completion(). If Thread A is scheduled first and increments
- * the counter, then gets swapped out, thread C may get scheduled and will
- * quickly go through compat_wait_for_completion() (since done != 0) while
- * thread B continues to sleep, even though thread B should have been the one
- * to wake up.
- */
-
-#include <asm/current.h>
-#include "compat_sched.h"
-#include "compat_list.h"
-#include <linux/smp_lock.h> // for lock_kernel()/unlock_kernel()
-#include "compat_wait.h"
-
-typedef struct compat_completion {
- unsigned int done;
- wait_queue_head_t wq;
-} compat_completion;
-
-#define compat_init_completion(comp) do { \
- (comp)->done = 0; \
- init_waitqueue_head(&(comp)->wq); \
-} while (0)
-#define COMPAT_DECLARE_COMPLETION(comp) \
- compat_completion comp = { \
- .done = 0, \
- .wq = __WAIT_QUEUE_HEAD_INITIALIZER((comp).wq), \
- }
-
-/*
- * Locking and unlocking the kernel lock here ensures that the thread
- * is no longer running in module code: compat_complete_and_exit
- * performs the sequence { lock_kernel(); up(comp); compat_exit(); }, with
- * the final unlock_kernel performed implicitly by the resident kernel
- * in do_exit.
- */
-#define compat_wait_for_completion(comp) do { \
- spin_lock_irq(&(comp)->wq.lock); \
- if (!(comp)->done) { \
- DECLARE_WAITQUEUE(wait, current); \
- wait.flags |= WQ_FLAG_EXCLUSIVE; \
- __add_wait_queue_tail(&(comp)->wq, &wait); \
- do { \
- __set_current_state(TASK_UNINTERRUPTIBLE); \
- spin_unlock_irq(&(comp)->wq.lock); \
- schedule(); \
- spin_lock_irq(&(comp)->wq.lock); \
- } while (!(comp)->done); \
- __remove_wait_queue(&(comp)->wq, &wait); \
- } \
- (comp)->done--; \
- spin_unlock_irq(&(comp)->wq.lock); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-/* XXX: I don't think I need to touch the BKL. */
-#define compat_complete(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done++; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up(&(comp)->wq); \
-} while (0)
-
-#define compat_complete_all(comp) do { \
- unsigned long flags; \
- spin_lock_irqsave(&(comp)->wq.lock, flags); \
- (comp)->done += UINT_MAX / 2; \
- spin_unlock_irqrestore(&(comp)->wq.lock, flags); \
- wake_up_all(&(comp)->wq); \
-} while (0)
-
-/*
- * Completions via semaphores.
- */
-#else
-
-#include "compat_semaphore.h"
-#define compat_completion struct semaphore
-#define compat_init_completion(comp) init_MUTEX_LOCKED(comp)
-#define COMPAT_DECLARE_COMPLETION(comp) DECLARE_MUTEX_LOCKED(comp)
-
-#define compat_wait_for_completion(comp) do { \
- down(comp); \
- lock_kernel(); \
- unlock_kernel(); \
-} while (0)
-
-#define compat_complete(comp) up(comp)
-
-#endif
-
-#endif /* __COMPAT_COMPLETION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_FILE_H__
-# define __COMPAT_FILE_H__
-
-
-/* The fput() API is modified in 2.2.0 --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define compat_fput(_file) fput(_file)
-#else
-# define compat_fput(_file) fput(_file, (_file)->f_inode)
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-# define compat_get_file(_file) get_file(_file)
-# define compat_file_count(_file) file_count(_file)
-#else
-# define compat_get_file(_file) (_file)->f_count++
-# define compat_file_count(_file) (_file)->f_count
-#endif
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 4)
-# define compat_filp_close(_file, _files) filp_close(_file, _files)
-#else
-static inline void compat_filp_close(struct file* filp, fl_owner_t files) {
- if (filp->f_op && filp->f_op->flush) {
- filp->f_op->flush(filp);
- }
- /*
- * Hopefully there are no locks to release on this filp.
- * locks_remove_posix is not exported so we cannot use it...
- */
- fput(filp);
-}
-#endif
-
-
-#endif /* __COMPAT_FILE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_FS_H__
-# define __COMPAT_FS_H__
-
-#include <linux/fs.h>
-
-/*
- * 2.6.5+ kernels define FS_BINARY_MOUNTDATA. Since it didn't exist and
- * wasn't used prior, it's safe to define it to zero.
- */
-
-#ifndef FS_BINARY_MOUNTDATA
-#define FS_BINARY_MOUNTDATA 0
-#endif
-
-/*
- * MAX_LFS_FILESIZE wasn't defined until 2.5.4.
- */
-#ifndef MAX_LFS_FILESIZE
-# include <linux/pagemap.h>
-# if BITS_PER_LONG == 32
-# define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG - 1)) - 1)
-# elif BITS_PER_LONG == 64
-# define MAX_LFS_FILESIZE 0x7fffffffffffffffUL
-# endif
-#endif
-
-
-/*
- * sendfile as a VFS op was born in 2.5.30. Unfortunately, it also changed
- * signatures, first in 2.5.47, then again in 2.5.70, then again in 2.6.8.
- * Luckily, the 2.6.8+ signature is the same as the 2.5.47 signature. And
- * as of 2.6.23-rc1 sendfile is gone, replaced by splice_read...
- *
- * Let's not support sendfile from 2.5.30 to 2.5.47, because the 2.5.30
- * signature is much different and file_send_actor isn't externed.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
-#define VMW_SENDFILE_NONE
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
-#define VMW_SENDFILE_NEW
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 70)
-#define VMW_SENDFILE_OLD
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 47)
-#define VMW_SENDFILE_NEW
-#else
-#define VMW_SENDFILE_NONE
-#endif
-
-/*
- * splice_read is there since 2.6.17, but let's avoid 2.6.17-rcX kernels...
- * After all nobody is using splice system call until 2.6.23 using it to
- * implement sendfile.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
-#define VMW_SPLICE_READ 1
-#endif
-
-/*
- * Filesystems wishing to use generic page cache read/write routines are
- * supposed to implement aio_read and aio_write (calling into
- * generic_file_aio_read() and generic_file_aio_write() if necessary).
- *
- * The VFS exports do_sync_read() and do_sync_write() as the "new"
- * generic_file_read() and generic_file_write(), but filesystems need not
- * actually implement read and write- the VFS will automatically call
- * do_sync_write() and do_sync_read() when applications invoke the standard
- * read() and write() system calls.
- *
- * In 2.6.19, generic_file_read() and generic_file_write() were removed,
- * necessitating this change. AIO dates as far back as 2.5.42, but the API has
- * changed over time, so for simplicity, we'll only enable it from 2.6.19 and
- * on.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
-# define VMW_USE_AIO
-#endif
-
-
-/*
- * The alloc_inode and destroy_inode VFS ops didn't exist prior to 2.4.21.
- * Without these functions, file systems can't embed inodes.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 21)
-# define VMW_EMBED_INODE
-#endif
-
-
-/*
- * iget() was removed from the VFS as of 2.6.25-rc1. The replacement for iget()
- * is iget_locked() which was added in 2.5.17.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 17)
-# define VMW_USE_IGET_LOCKED
-#endif
-
-/*
- * parent_ino was born in 2.5.5. For older kernels, let's use 2.5.5
- * implementation. It uses the dcache lock which is OK because per-dentry
- * locking appeared after 2.5.5.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-#define compat_parent_ino(dentry) parent_ino(dentry)
-#else
-#define compat_parent_ino(dentry) \
-({ \
- ino_t res; \
- spin_lock(&dcache_lock); \
- res = dentry->d_parent->d_inode->i_ino; \
- spin_unlock(&dcache_lock); \
- res; \
-})
-#endif
-
-
-/*
- * putname changed to __putname in 2.6.6.
- */
-#define compat___getname() __getname()
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
-#define compat___putname(name) putname(name)
-#else
-#define compat___putname(name) __putname(name)
-#endif
-
-
-/*
- * inc_nlink, drop_nlink, and clear_nlink were added in 2.6.19.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#define compat_inc_nlink(inode) ((inode)->i_nlink++)
-#define compat_drop_nlink(inode) ((inode)->i_nlink--)
-#define compat_clear_nlink(inode) ((inode)->i_nlink = 0)
-#else
-#define compat_inc_nlink(inode) inc_nlink(inode)
-#define compat_drop_nlink(inode) drop_nlink(inode)
-#define compat_clear_nlink(inode) clear_nlink(inode)
-#endif
-
-
-/*
- * i_size_write and i_size_read were introduced in 2.6.0-test1
- * (though we'll look for them as of 2.6.1). They employ slightly different
- * locking in order to guarantee atomicity, depending on the length of a long,
- * whether the kernel is SMP, or whether the kernel is preemptible. Prior to
- * i_size_write and i_size_read, there was no such locking, so that's the
- * behavior we'll emulate.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 1)
-#define compat_i_size_read(inode) ((inode)->i_size)
-#define compat_i_size_write(inode, size) ((inode)->i_size = size)
-#else
-#define compat_i_size_read(inode) i_size_read(inode)
-#define compat_i_size_write(inode, size) i_size_write(inode, size)
-#endif
-
-
-/*
- * filemap_fdatawrite was introduced in 2.5.12. Prior to that, modules used
- * filemap_fdatasync instead. In 2.4.18, both filemap_fdatawrite and
- * filemap_fdatawait began returning status codes. Prior to that, they were
- * void functions, so we'll just have them return 0.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 18)
-#define compat_filemap_fdatawrite(mapping) \
-({ \
- int result = 0; \
- filemap_fdatasync(mapping); \
- result; \
-})
-#define compat_filemap_fdatawait(mapping) \
-({ \
- int result = 0; \
- filemap_fdatawait(mapping); \
- result; \
-})
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12)
-#define compat_filemap_fdatawrite(mapping) filemap_fdatasync(mapping)
-#define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping)
-#else
-#define compat_filemap_fdatawrite(mapping) filemap_fdatawrite(mapping)
-#define compat_filemap_fdatawait(mapping) filemap_fdatawait(mapping)
-#endif
-
-
-/*
- * filemap_write_and_wait was introduced in 2.6.6 and exported for module use
- * in 2.6.16. It's really just a simple wrapper around filemap_fdatawrite and
- * and filemap_fdatawait, which initiates a flush of all dirty pages, then
- * waits for the pages to flush. The implementation here is a simplified form
- * of the one found in 2.6.20-rc3.
- *
- * Unfortunately, it just isn't possible to implement this prior to 2.4.5, when
- * neither filemap_fdatawait nor filemap_fdatasync were exported for module
- * use. So we'll define it out and hope for the best.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 5)
-#define compat_filemap_write_and_wait(mapping)
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
-#define compat_filemap_write_and_wait(mapping) \
-({ \
- int result = 0; \
- if (mapping->nrpages) { \
- result = compat_filemap_fdatawrite(mapping); \
- if (result != -EIO) { \
- int result2 = compat_filemap_fdatawait(mapping); \
- if (!result) { \
- result = result2; \
- } \
- } \
- } \
- result; \
-})
-#else
-#define compat_filemap_write_and_wait(mapping) filemap_write_and_wait(mapping)
-#endif
-
-
-/*
- * invalidate_remote_inode was introduced in 2.6.0-test5. Prior to that,
- * filesystems wishing to invalidate pages belonging to an inode called
- * invalidate_inode_pages.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-#define compat_invalidate_remote_inode(inode) invalidate_inode_pages(inode)
-#else
-#define compat_invalidate_remote_inode(inode) invalidate_remote_inode(inode)
-#endif
-
-#endif /* __COMPAT_FS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1999 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_init.h: Initialization compatibility wrappers.
- */
-
-#ifndef __COMPAT_INIT_H__
-#define __COMPAT_INIT_H__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-#include <linux/init.h>
-#endif
-
-#ifndef module_init
-#define module_init(x) int init_module(void) { return x(); }
-#endif
-
-#ifndef module_exit
-#define module_exit(x) void cleanup_module(void) { x(); }
-#endif
-
-#endif /* __COMPAT_INIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_KERNEL_H__
-# define __COMPAT_KERNEL_H__
-
-#include <asm/unistd.h>
-#include <linux/kernel.h>
-
-/*
- * container_of was introduced in 2.5.28 but it's easier to check like this.
- */
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-/*
- * wait_for_completion and friends did not exist before 2.4.9.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)
-
-#define compat_complete_and_exit(comp, status) complete_and_exit(comp, status)
-
-#else
-
-#include "compat_completion.h"
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-#define __NR_compat_exit __NR_exit
-static inline _syscall1(int, compat_exit, int, exit_code);
-
-/*
- * See compat_wait_for_completion in compat_completion.h.
- * compat_exit implicitly performs an unlock_kernel, in resident code,
- * ensuring that the thread is no longer running in module code when the
- * module is unloaded.
- */
-#define compat_complete_and_exit(comp, status) do { \
- lock_kernel(); \
- compat_complete(comp); \
- compat_exit(status); \
-} while (0)
-
-#endif
-
-/*
- * vsnprintf became available in 2.4.10. For older kernels, just fall back on
- * vsprintf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define vsnprintf(str, size, fmt, args) vsprintf(str, fmt, args)
-#endif
-
-#endif /* __COMPAT_KERNEL_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_LIST_H__
-# define __COMPAT_LIST_H__
-
-#include <linux/list.h>
-
-/*
- * list_add_tail is with us since 2.4.0, or something like that.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define list_add_tail(newe, head) do { \
- struct list_head *__h = (head); \
- __list_add((newe), __h->prev, __h); \
-} while (0)
-#endif
-
-/*
- * list_for_each_safe() showed up in 2.4.10, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_safe
-# define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-#endif
-
-/*
- * list_for_each_entry() showed up in 2.4.20, but it may be backported so we
- * just check for its existence.
- */
-#ifndef list_for_each_entry
-# define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-#endif
-
-#endif /* __COMPAT_LIST_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_MM_H__
-# define __COMPAT_MM_H__
-
-
-#include <linux/mm.h>
-
-
-/* The get_page() API appeared in 2.3.7 --hpreg */
-/* Sometime during development it became function instead of macro --petr */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(get_page)
-# define get_page(_page) atomic_inc(&(_page)->count)
-/* The __free_page() API is exported in 2.1.67 --hpreg */
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 67)
-# define put_page __free_page
-# else
-# include "compat_page.h"
-
-# define page_to_phys(_page) (page_to_pfn(_page) << PAGE_SHIFT)
-# define put_page(_page) free_page(page_to_phys(_page))
-# endif
-#endif
-
-
-/* page_count() is 2.4.0 invention. Unfortunately unavailable in some RedHat
- * kernels (for example 2.4.21-4-RHEL3). */
-/* It is function since 2.6.0, and hopefully RedHat will not play silly games
- * with mm_inline.h again... */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(page_count)
-# define page_count(page) atomic_read(&(page)->count)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-# define compat_vm_pgoff(vma) ((vma)->vm_offset >> PAGE_SHIFT)
-
-static inline unsigned long compat_do_mmap_pgoff(struct file *file, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flag, unsigned long pgoff)
-{
- unsigned long ret = -EINVAL;
-
- if (pgoff < 1 << (32 - PAGE_SHIFT)) {
- ret = do_mmap(file, addr, len, prot, flag, pgoff << PAGE_SHIFT);
- }
- return ret;
-}
-
-#else
-# define compat_vm_pgoff(vma) (vma)->vm_pgoff
-# ifdef VMW_SKAS_MMAP
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(current->mm, f, a, l, p, g, o)
-# else
-# define compat_do_mmap_pgoff(f, a, l, p, g, o) \
- do_mmap_pgoff(f, a, l, p, g, o)
-# endif
-#endif
-
-
-/* 2.2.x uses 0 instead of some define */
-#ifndef NOPAGE_SIGBUS
-#define NOPAGE_SIGBUS (0)
-#endif
-
-
-/* 2.2.x does not have HIGHMEM support */
-#ifndef GFP_HIGHUSER
-#define GFP_HIGHUSER (GFP_USER)
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-
-#include "compat_page.h"
-
-static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
-{
- unsigned long addr;
-
- addr = __get_free_pages(gfp_mask, order);
- if (!addr) {
- return NULL;
- }
- return virt_to_page(addr);
-}
-#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
-
-#endif
-
-/*
- * In 2.4.14, the logic behind the UnlockPage macro was moved to the
- * unlock_page() function. Later (in 2.5.12), the UnlockPage macro was removed
- * altogether, and nowadays everyone uses unlock_page().
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 14)
-#define compat_unlock_page(page) UnlockPage(page)
-#else
-#define compat_unlock_page(page) unlock_page(page)
-#endif
-
-/*
- * In 2.4.10, vmtruncate was changed from returning void to returning int.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
-#define compat_vmtruncate(inode, size) \
-({ \
- int result = 0; \
- vmtruncate(inode, size); \
- result; \
-})
-#else
-#define compat_vmtruncate(inode, size) vmtruncate(inode, size)
-#endif
-
-
-#endif /* __COMPAT_MM_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * compat_module.h --
- */
-
-#ifndef __COMPAT_MODULE_H__
-# define __COMPAT_MODULE_H__
-
-
-#include <linux/module.h>
-
-
-/*
- * Modules wishing to use the GPL license are required to include a
- * MODULE_LICENSE definition in their module source as of 2.4.10.
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-/*
- * To make use of our own home-brewed MODULE_INFO, we need macros to
- * concatenate two expressions to "__mod_", and and to convert an
- * expression into a string. I'm sure we've got these in our codebase,
- * but I'd rather not introduce such a dependency in a compat header.
- */
-#ifndef __module_cat
-#define __module_cat_1(a, b) __mod_ ## a ## b
-#define __module_cat(a, b) __module_cat_1(a, b)
-#endif
-
-#ifndef __stringify
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
-#endif
-
-/*
- * MODULE_INFO was born in 2.5.69.
- */
-#ifndef MODULE_INFO
-#define MODULE_INFO(tag, info) \
-static const char __module_cat(tag, __LINE__)[] \
- __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info
-#endif
-
-/*
- * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx"
- * string to the module's version, but that was removed in 2.6.10, so we'll
- * ignore it in our wrapper.
- */
-#ifndef MODULE_VERSION
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-#endif
-
-#endif /* __COMPAT_MODULE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_NAMEI_H__
-# define __COMPAT_NAMEI_H__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18)
-#include <linux/namei.h>
-#endif
-
-/*
- * In 2.6.25-rc2, dentry and mount objects were removed from the nameidata
- * struct. They were both replaced with a struct path.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
-#define compat_vmw_nd_to_dentry(nd) (nd).path.dentry
-#else
-#define compat_vmw_nd_to_dentry(nd) (nd).dentry
-#endif
-
-/* In 2.6.25-rc2, path_release(&nd) was replaced with path_put(&nd.path). */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
-#define compat_path_release(nd) path_put(&(nd)->path)
-#else
-#define compat_path_release(nd) path_release(nd)
-#endif
-
-/* path_lookup was exported in 2.4.25 */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
-#define compat_path_lookup(path, flags, nd) path_lookup(path, flags, nd)
-#else
-#define compat_path_lookup(path, flags, nd) \
- ({ \
- int ret = 0; \
- if (path_init(path, flags, nd)) { \
- ret = path_walk(path, nd); \
- } \
- ret; \
- })
-#endif
-
-#endif /* __COMPAT_NAMEI_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_PAGE_H__
-# define __COMPAT_PAGE_H__
-
-
-#include <linux/mm.h>
-#include <asm/page.h>
-
-
-/* The pfn_to_page() API appeared in 2.5.14 and changed to function during 2.6.x */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pfn_to_page)
-# define pfn_to_page(_pfn) (mem_map + (_pfn))
-# define page_to_pfn(_page) ((_page) - mem_map)
-#endif
-
-
-/* The virt_to_page() API appeared in 2.4.0 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) && !defined(virt_to_page)
-# define virt_to_page(_kvAddr) pfn_to_page(MAP_NR(_kvAddr))
-#endif
-
-
-/*
- * The get_order() API appeared at some point in 2.3.x, and was then backported
- * in 2.2.17-21mdk and in the stock 2.2.18. Because we can only detect its
- * definition through makefile tricks, we provide our own for now --hpreg
- */
-static inline int
-compat_get_order(unsigned long size) // IN
-{
- int order;
-
- size = (size - 1) >> (PAGE_SHIFT - 1);
- order = -1;
- do {
- size >>= 1;
- order++;
- } while (size);
-
- return order;
-}
-
-/*
- * BUG() was added to <asm/page.h> in 2.2.18, and was moved to <asm/bug.h>
- * in 2.5.58.
- *
- * XXX: Technically, this belongs in some sort of "compat_asm_page.h" file, but
- * since our compatibility wrappers don't distinguish between <asm/xxx.h> and
- * <linux/xxx.h>, putting it here is reasonable.
- */
-#ifndef BUG
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- __asm__ __volatile__(".byte 0x0f,0x0b"); \
-} while (0)
-#endif
-
-#endif /* __COMPAT_PAGE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SCHED_H__
-# define __COMPAT_SCHED_H__
-
-
-#include <linux/sched.h>
-
-/* CLONE_KERNEL available in 2.5.35 and higher. */
-#ifndef CLONE_KERNEL
-#define CLONE_KERNEL CLONE_FILES | CLONE_FS | CLONE_SIGHAND
-#endif
-
-/* TASK_COMM_LEN become available in 2.6.11. */
-#ifndef TASK_COMM_LEN
-#define TASK_COMM_LEN 16
-#endif
-
-/* The capable() API appeared in 2.1.92 --hpreg */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 92)
-# define capable(_capability) suser()
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-# define need_resched() need_resched
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define need_resched() (current->need_resched)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 3)
-# define cond_resched() (need_resched() ? schedule() : (void) 0)
-#endif
-
-/* Oh well. We need yield... Happy us! */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20)
-# ifdef __x86_64__
-# define compat_yield() there_is_nothing_like_yield()
-# else
-# include <linux/unistd.h>
-# include <linux/kernel.h>
-
-/*
- * Used by _syscallX macros. Note that this is global variable, so
- * do not rely on its contents too much. As exit() is only function
- * we use, and we never check return value from exit(), we have
- * no problem...
- */
-extern int errno;
-
-/*
- * compat_exit() provides an access to the exit() function. It must
- * be named compat_exit(), as exit() (with different signature) is
- * provided by x86-64, arm and other (but not by i386).
- */
-# define __NR_compat_yield __NR_sched_yield
-static inline _syscall0(int, compat_yield);
-# endif
-#else
-# define compat_yield() yield()
-#endif
-
-
-/*
- * Since 2.5.34 there are two methods to enumerate tasks:
- * for_each_process(p) { ... } which enumerates only tasks and
- * do_each_thread(g,t) { ... } while_each_thread(g,t) which enumerates
- * also threads even if they share same pid.
- */
-#ifndef for_each_process
-# define for_each_process(p) for_each_task(p)
-#endif
-
-#ifndef do_each_thread
-# define do_each_thread(g, t) for_each_task(g) { t = g; do
-# define while_each_thread(g, t) while (0) }
-#endif
-
-
-/*
- * Lock for signal mask is moving target...
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 40) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_sigmask_lock sigmask_lock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 60) && !defined(INIT_SIGHAND)
-/* RedHat's 2.4.x with first version of NPTL support, or 2.5.40 to 2.5.59 */
-#define compat_sigmask_lock sig->siglock
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-/* RedHat's 2.4.x with second version of NPTL support, or 2.5.60+. */
-#define compat_sigmask_lock sighand->siglock
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(¤t->blocked, (siginfo_ptr))
-#else
-#define compat_dequeue_signal_current(siginfo_ptr) \
- dequeue_signal(current, ¤t->blocked, (siginfo_ptr))
-#endif
-#endif
-
-/*
- * recalc_sigpending() had task argument in the past
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 29) && defined(CLONE_PID)
-/* 2.4.x without NPTL patches or early 2.5.x */
-#define compat_recalc_sigpending() recalc_sigpending(current)
-#else
-/* RedHat's 2.4.x with NPTL support, or 2.5.29+ */
-#define compat_recalc_sigpending() recalc_sigpending()
-#endif
-
-
-/*
- * reparent_to_init() was introduced in 2.4.8. In 2.5.38 (or possibly
- * earlier, but later than 2.5.31) a call to it was added into
- * daemonize(), so compat_daemonize no longer needs to call it.
- *
- * In 2.4.x kernels reparent_to_init() forgets to do correct refcounting
- * on current->user. It is better to count one too many than one too few...
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 38)
-#define compat_reparent_to_init() do { \
- reparent_to_init(); \
- atomic_inc(¤t->user->__count); \
- } while (0)
-#else
-#define compat_reparent_to_init() do {} while (0)
-#endif
-
-
-/*
- * daemonize appeared in 2.2.18. Except 2.2.17-4-RH7.0, which has it too.
- * Fortunately 2.2.17-4-RH7.0 uses versioned symbols, so we can check
- * its existence with defined().
- */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) && !defined(daemonize)
-static inline void daemonize(void) {
- struct fs_struct *fs;
-
- exit_mm(current);
- current->session = 1;
- current->pgrp = 1;
- exit_fs(current);
- fs = init_task.fs;
- current->fs = fs;
- atomic_inc(&fs->count);
-}
-#endif
-
-
-/*
- * flush_signals acquires sighand->siglock since 2.5.61... Verify RH's kernels!
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_flush_signals(task) do { \
- spin_lock_irq(&task->compat_sigmask_lock); \
- flush_signals(task); \
- spin_unlock_irq(&task->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_flush_signals(task) flush_signals(task)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_allow_signal(signr) do { \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigdelset(¤t->blocked, signr); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- } while (0)
-#else
-#define compat_allow_signal(signr) allow_signal(signr)
-#endif
-
-/*
- * daemonize can set process name since 2.5.61. Prior to 2.5.61, daemonize
- * didn't block signals on our behalf.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 61)
-#define compat_daemonize(x...) \
-({ \
- /* Beware! No snprintf here, so verify arguments! */ \
- sprintf(current->comm, x); \
- \
- /* Block all signals. */ \
- spin_lock_irq(¤t->compat_sigmask_lock); \
- sigfillset(¤t->blocked); \
- compat_recalc_sigpending(); \
- spin_unlock_irq(¤t->compat_sigmask_lock); \
- compat_flush_signals(current); \
- \
- daemonize(); \
- compat_reparent_to_init(); \
-})
-#else
-#define compat_daemonize(x...) daemonize(x)
-#endif
-
-
-/*
- * set priority for specified thread. Exists on 2.6.x kernels and some
- * 2.4.x vendor's kernels.
- */
-#if defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) set_user_nice((task), (n))
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
-#define compat_set_user_nice(task, n) do { (task)->priority = 20 - (n); } while (0)
-#elif !defined(VMW_HAVE_SET_USER_NICE)
-#define compat_set_user_nice(task, n) do { (task)->nice = (n); } while (0)
-#endif
-
-/*
- * try to freeze a process. For kernels 2.6.11 or newer, we know how to choose
- * the interface. The problem is that the oldest interface, introduced in
- * 2.5.18, was backported to 2.4.x kernels. So if we're older than 2.6.11,
- * we'll decide what to do based on whether or not swsusp was configured
- * for the kernel. For kernels 2.6.20 and newer, we'll also need to include
- * freezer.h since the try_to_freeze definition was pulled out of sched.h.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-#include <linux/freezer.h>
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) || defined(VMW_TL10S64_WORKAROUND)
-#define compat_try_to_freeze() try_to_freeze()
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
-#define compat_try_to_freeze() try_to_freeze(PF_FREEZE)
-#elif defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_SOFTWARE_SUSPEND2)
-#include "compat_mm.h"
-#include <linux/errno.h>
-#include <linux/suspend.h>
-static inline int compat_try_to_freeze(void) {
- if (current->flags & PF_FREEZE) {
- refrigerator(PF_FREEZE);
- return 1;
- } else {
- return 0;
- }
-}
-#else
-static inline int compat_try_to_freeze(void) { return 0; }
-#endif
-
-/*
- * As of 2.6.23-rc1, kernel threads are no longer freezable by
- * default. Instead, kernel threads that need to be frozen must opt-in
- * by calling set_freezable() as soon as the thread is created.
- */
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
-#define compat_set_freezable() do { set_freezable(); } while (0)
-#else
-#define compat_set_freezable() do {} while (0)
-#endif
-
-/*
- * Around 2.6.27 kernel stopped sending signals to kernel
- * threads being frozen, instead threads have to check
- * freezing() or use wait_event_freezable(). Unfortunately
- * wait_event_freezable() completely hides the fact that
- * thread was frozen from calling code and sometimes we do
- * want to know that.
- */
-#ifdef PF_FREEZER_NOSIG
-#define compat_wait_check_freezing() freezing(current)
-#else
-#define compat_wait_check_freezing() (0)
-#endif
-
-/*
- * Since 2.6.27-rc2 kill_proc() is gone... Replacement (GPL-only!)
- * API is available since 2.6.19. Use them from 2.6.27-rc1 up.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-typedef int compat_pid;
-#define compat_find_get_pid(pid) (pid)
-#define compat_put_pid(pid) do { } while (0)
-#define compat_kill_pid(pid, sig, flag) kill_proc(pid, sig, flag)
-#else
-typedef struct pid * compat_pid;
-#define compat_find_get_pid(pid) find_get_pid(pid)
-#define compat_put_pid(pid) put_pid(pid)
-#define compat_kill_pid(pid, sig, flag) kill_pid(pid, sig, flag)
-#endif
-
-
-#endif /* __COMPAT_SCHED_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SEMAPHORE_H__
-# define __COMPAT_SEMAPHORE_H__
-
-
-/* <= 2.6.25 have asm only, 2.6.26 has both, and 2.6.27-rc2+ has linux only. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-# include <asm/semaphore.h>
-#else
-# include <linux/semaphore.h>
-#endif
-
-
-/*
-* The init_MUTEX_LOCKED() API appeared in 2.2.18, and is also in
-* 2.2.17-21mdk --hpreg
-*/
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
- #ifndef init_MUTEX_LOCKED
- #define init_MUTEX_LOCKED(_sem) *(_sem) = MUTEX_LOCKED
- #endif
- #ifndef DECLARE_MUTEX
- #define DECLARE_MUTEX(name) struct semaphore name = MUTEX
- #endif
- #ifndef DECLARE_MUTEX_LOCKED
- #define DECLARE_MUTEX_LOCKED(name) struct semaphore name = MUTEX_LOCKED
- #endif
-#endif
-
-
-#endif /* __COMPAT_SEMAPHORE_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SLAB_H__
-# define __COMPAT_SLAB_H__
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# include <linux/slab.h>
-#else
-# include <linux/malloc.h>
-#endif
-
-/*
- * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache
- * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and
- * afterwards it was renamed to kmem_cache. Here we keep things simple and use
- * the accepted typedef until it became deprecated, at which point we switch
- * over to the kmem_cache name.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-# define compat_kmem_cache struct kmem_cache
-#else
-# define compat_kmem_cache kmem_cache_t
-#endif
-
-/*
- * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags,
- * constructor, and destructor. Then for some time kernel was asserting that
- * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5
- * arguments - destructor is gone.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR)
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor, NULL)
-#else
-#define compat_kmem_cache_create(name, size, align, flags, ctor) \
- kmem_cache_create(name, size, align, flags, ctor)
-#endif
-
-/*
- * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to
- * prepare (aka "this"), from which cache it came, and some unused flags. After
- * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped...
- * Since 2.6.27-rc2 everything is different again, and ctor has only one argument.
- *
- * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_3_ARGS
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-# define VMW_KMEMCR_CTOR_HAS_2_ARGS
-#endif
-
-#if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS)
-typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \
- compat_kmem_cache *cache, \
- unsigned long flags
-#elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS)
-typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \
- void *arg
-#else
-typedef void compat_kmem_cache_ctor(void *);
-#define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg
-#endif
-
-#endif /* __COMPAT_SLAB_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_SPINLOCK_H__
-# define __COMPAT_SPINLOCK_H__
-
-
-/*
- * The spin_lock() API appeared in 2.1.25 in asm/smp_lock.h
- * It moved in 2.1.30 to asm/spinlock.h
- * It moved again in 2.3.18 to linux/spinlock.h
- *
- * --hpreg
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 18)
-# include <linux/spinlock.h>
-#else
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30)
-# include <asm/spinlock.h>
-# else
-typedef struct {} spinlock_t;
-# define spin_lock_init(lock)
-# define spin_lock(lock)
-# define spin_unlock(lock)
-# define spin_lock_irqsave(lock, flags) do { \
- save_flags(flags); \
- cli(); \
- spin_lock(lock); \
- } while (0)
-# define spin_unlock_irqrestore(lock, flags) do { \
- spin_unlock(lock); \
- restore_flags(flags); \
- } while (0)
-# endif
-#endif
-
-
-/*
- * Preempt support was added during 2.5.x development cycle, and later
- * it was backported to 2.4.x. In 2.4.x backport these definitions
- * live in linux/spinlock.h, that's why we put them here (in 2.6.x they
- * are defined in linux/preempt.h which is included by linux/spinlock.h).
- */
-#ifdef CONFIG_PREEMPT
-#define compat_preempt_disable() preempt_disable()
-#define compat_preempt_enable() preempt_enable()
-#else
-#define compat_preempt_disable() do { } while (0)
-#define compat_preempt_enable() do { } while (0)
-#endif
-
-
-#endif /* __COMPAT_SPINLOCK_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_STATFS_H__
-# define __COMPAT_STATFS_H__
-
-/* vfs.h simply include statfs.h, but it knows what directory statfs.h is in. */
-#include <linux/vfs.h>
-
-/* 2.5.74 renamed struct statfs to kstatfs. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 74)
-#define compat_kstatfs kstatfs
-#else
-#define compat_kstatfs statfs
-#endif
-
-#endif /* __COMPAT_STATFS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_STRING_H__
-# define __COMPAT_STRING_H__
-
-#include <linux/string.h>
-
-/*
- * kstrdup was born in 2.6.13. This implementation is almost identical to the
- * one found there.
- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
-#define compat_kstrdup(s, gfp) kstrdup(s, gfp)
-#else
-#define compat_kstrdup(s, gfp) \
-({ \
- size_t len; \
- char *buf; \
- len = strlen(s) + 1; \
- buf = kmalloc(len, gfp); \
- memcpy(buf, s, len); \
- buf; \
-})
-#endif
-
-#endif /* __COMPAT_STRING_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_UACCESS_H__
-# define __COMPAT_UACCESS_H__
-
-
-/* User space access functions moved in 2.1.7 to asm/uaccess.h --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 7)
-# include <asm/uaccess.h>
-#else
-# include <asm/segment.h>
-#endif
-
-
-/* get_user() API modified in 2.1.4 to take 2 arguments --hpreg */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 4)
-# define compat_get_user get_user
-#else
-/*
- * We assign 0 to the variable in case of failure to prevent "`_var' might be
- * used uninitialized in this function" compiler warnings. I think it is OK,
- * because the hardware-based version in newer kernels probably has the same
- * semantics and does not guarantee that the value of _var will not be
- * modified, should the access fail --hpreg
- */
-# define compat_get_user(_var, _uvAddr) ({ \
- int _status; \
- \
- _status = verify_area(VERIFY_READ, _uvAddr, sizeof(*(_uvAddr))); \
- if (_status == 0) { \
- (_var) = get_user(_uvAddr); \
- } else { \
- (_var) = 0; \
- } \
- _status; \
-})
-#endif
-
-
-/*
- * The copy_from_user() API appeared in 2.1.4
- *
- * The emulation is not perfect here, but it is conservative: on failure, we
- * always return the total size, instead of the potentially smaller faulty
- * size --hpreg
- *
- * Since 2.5.55 copy_from_user() is no longer macro.
- */
-#if !defined(copy_from_user) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0)
-# define copy_from_user(_to, _from, _size) ( \
- verify_area(VERIFY_READ, _from, _size) \
- ? (_size) \
- : (memcpy_fromfs(_to, _from, _size), 0) \
-)
-# define copy_to_user(_to, _from, _size) ( \
- verify_area(VERIFY_WRITE, _to, _size) \
- ? (_size) \
- : (memcpy_tofs(_to, _from, _size), 0) \
-)
-#endif
-
-
-#endif /* __COMPAT_UACCESS_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_VERSION_H__
-# define __COMPAT_VERSION_H__
-
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-
-#ifndef __linux__
-# error "linux-version.h"
-#endif
-
-
-#include <linux/version.h>
-
-/* Appeared in 2.1.90 --hpreg */
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#endif
-
-
-/*
- * Distinguish relevant classes of Linux kernels.
- *
- * The convention is that version X defines all
- * the KERNEL_Y symbols where Y <= X.
- *
- * XXX Do not add more definitions here. This way of doing things does not
- * scale, and we are going to phase it out soon --hpreg
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0)
-# define KERNEL_2_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0)
-# define KERNEL_2_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1)
-# define KERNEL_2_3_1
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15)
-/* new networking */
-# define KERNEL_2_3_15
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25)
-/* new procfs */
-# define KERNEL_2_3_25
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29)
-/* even newer procfs */
-# define KERNEL_2_3_29
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43)
-/* softnet changes */
-# define KERNEL_2_3_43
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47)
-/* more softnet changes */
-# define KERNEL_2_3_47
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99)
-/* name in netdevice struct is array and not pointer */
-# define KERNEL_2_3_99
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-/* New 'owner' member at the beginning of struct file_operations */
-# define KERNEL_2_4_0
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8)
-/* New netif_rx_ni() --hpreg */
-# define KERNEL_2_4_8
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
-/* New vmap() */
-# define KERNEL_2_4_22
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2)
-/* New kdev_t, major()/minor() API --hpreg */
-# define KERNEL_2_5_2
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
-/* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */
-# define KERNEL_2_5_5
-#endif
-
-
-#endif /* __COMPAT_VERSION_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_WAIT_H__
-# define __COMPAT_WAIT_H__
-
-
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/file.h>
-
-#include "compat_file.h"
-
-
-/*
- * The DECLARE_WAITQUEUE() API appeared in 2.3.1
- * It was back ported in 2.2.18
- *
- * --hpreg
- */
-
-#ifndef DECLARE_WAITQUEUE
-
-typedef struct wait_queue *wait_queue_head_t;
-# define init_waitqueue_head(_headPtr) *(_headPtr) = NULL
-# define DECLARE_WAITQUEUE(_var, _task) \
- struct wait_queue _var = {_task, NULL, }
-
-typedef struct wait_queue wait_queue_t;
-# define init_waitqueue_entry(_wait, _task) ((_wait)->task = (_task))
-
-#endif
-
-/*
- * The 'struct poll_wqueues' appeared in 2.5.48, when global
- * /dev/epoll interface was added. It was backported to the
- * 2.4.20-wolk4.0s.
- */
-
-#ifdef VMW_HAVE_EPOLL // {
-#define compat_poll_wqueues struct poll_wqueues
-#else // } {
-#define compat_poll_wqueues poll_table
-#endif // }
-
-#ifdef VMW_HAVE_EPOLL // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- poll_initwait((table)), \
- (wait) = &(table)->pt \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) // {
-
-/* If prototype does not match, build will abort here */
-extern void poll_initwait(compat_poll_wqueues *);
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), \
- poll_initwait(wait) \
-)
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((table)) \
-)
-
-#else // } {
-
-#define compat_poll_initwait(wait, table) ( \
- (wait) = (table), /* confuse compiler */ \
- (wait) = (poll_table *) __get_free_page(GFP_KERNEL), \
- (wait)->nr = 0, \
- (wait)->entry = (struct poll_table_entry *)((wait) + 1), \
- (wait)->next = NULL \
-)
-
-static inline void
-poll_freewait(poll_table *wait)
-{
- while (wait) {
- struct poll_table_entry * entry;
- poll_table *old;
-
- entry = wait->entry + wait->nr;
- while (wait->nr > 0) {
- wait->nr--;
- entry--;
- remove_wait_queue(entry->wait_address, &entry->wait);
- compat_fput(entry->filp);
- }
- old = wait;
- wait = wait->next;
- free_page((unsigned long) old);
- }
-}
-
-#define compat_poll_freewait(wait, table) ( \
- poll_freewait((wait)) \
-)
-
-#endif // }
-
-/*
- * The wait_event_interruptible_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_interruptible_timeout
-#define __wait_event_interruptible_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) \
- break; \
- if (!signal_pending(current)) { \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- continue; \
- } \
- ret = -ERESTARTSYS; \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_interruptible_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_interruptible_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * The wait_event_timeout() interface is not
- * defined in pre-2.6 kernels.
- */
-#ifndef wait_event_timeout
-#define __wait_event_timeout(wq, condition, ret) \
-do { \
- wait_queue_t __wait; \
- init_waitqueue_entry(&__wait, current); \
- \
- add_wait_queue(&wq, &__wait); \
- for (;;) { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- if (condition) \
- break; \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- } \
- set_current_state(TASK_RUNNING); \
- remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_timeout(wq, condition, timeout) \
-({ \
- long __ret = timeout; \
- if (!(condition)) \
- __wait_event_timeout(wq, condition, __ret); \
- __ret; \
-})
-#endif
-
-/*
- * DEFINE_WAIT() and friends were added in 2.5.39 and backported to 2.4.28.
- *
- * Unfortunately it is not true. While some distros may have done it the
- * change has never made it into vanilla 2.4 kernel. Instead of testing
- * particular kernel versions let's just test for presence of DEFINE_WAIT
- * when figuring out whether we need to provide replacement implementation
- * or simply alias existing one.
- */
-
-#ifndef DEFINE_WAIT
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DECLARE_WAITQUEUE(_wait, current)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- add_wait_queue(_sleep, _wait); \
- } while (0)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- set_current_state(_state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- do { \
- __set_current_state(_state); \
- remove_wait_queue(_sleep, _wait); \
- } while (0)
-
-#else
-
-# define COMPAT_DEFINE_WAIT(_wait) \
- DEFINE_WAIT(_wait)
-# define compat_init_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_cont_prepare_to_wait(_sleep, _wait, _state) \
- prepare_to_wait(_sleep, _wait, _state)
-# define compat_finish_wait(_sleep, _wait, _state) \
- finish_wait(_sleep, _wait)
-
-#endif /* #ifndef DEFINE_WAIT */
-
-#endif /* __COMPAT_WAIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __COMPAT_WORKQUEUE_H__
-# define __COMPAT_WORKQUEUE_H__
-
-#include <linux/kernel.h>
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)
-# include <linux/workqueue.h>
-#endif
-
-/*
- *
- * Work queues and delayed work queues.
- *
- * Prior to 2.5.41, the notion of work queues did not exist. Taskqueues are
- * used for work queues and timers are used for delayed work queues.
- *
- * After 2.6.20, normal work structs ("work_struct") and delayed work
- * ("delayed_work") structs were separated so that the work_struct could be
- * slimmed down. The interface was also changed such that the address of the
- * work_struct itself is passed in as the argument to the work function. This
- * requires that one embed the work struct in the larger struct containing the
- * information necessary to complete the work and use container_of() to obtain
- * the address of the containing structure.
- *
- * Users of these macros should embed a compat_work or compat_delayed_work in
- * a larger structure, then specify the larger structure as the _data argument
- * for the initialization functions, specify the work function to take
- * a compat_work_arg or compat_delayed_work_arg, then use the appropriate
- * _GET_DATA macro to obtain the reference to the structure passed in as _data.
- * An example is below.
- *
- *
- * typedef struct WorkData {
- * int data;
- * compat_work work;
- * } WorkData;
- *
- *
- * void
- * WorkFunc(compat_work_arg data)
- * {
- * WorkData *workData = COMPAT_WORK_GET_DATA(data, WorkData, work);
- *
- * ...
- * }
- *
- *
- * {
- * WorkData *workData = kmalloc(sizeof *workData, GFP_EXAMPLE);
- * if (!workData) {
- * return -ENOMEM;
- * }
- *
- * COMPAT_INIT_WORK(&workData->work, WorkFunc, workData);
- * compat_schedule_work(&workData->work);
- * }
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 41) /* { */
-typedef struct tq_struct compat_work;
-typedef struct compat_delayed_work {
- struct tq_struct work;
- struct timer_list timer;
-} compat_delayed_work;
-typedef void * compat_work_arg;
-typedef void * compat_delayed_work_arg;
-
-/*
- * Delayed work queues need to run at some point in the future in process
- * context, but task queues don't support delaying the task one is scheduling.
- * Timers allow us to delay the execution of our work queue until the future,
- * but timer handlers run in bottom-half context. As such, we use both a timer
- * and task queue and use the timer handler below to schedule the task in
- * process context immediately. The timer lets us delay execution, and the
- * task queue lets us run in process context.
- *
- * Note that this is similar to how delayed_work is implemented with work
- * queues in later kernel versions.
- */
-static inline void
-__compat_delayed_work_timer(unsigned long arg)
-{
- compat_delayed_work *dwork = (compat_delayed_work *)arg;
- if (dwork) {
- schedule_task(&dwork->work);
- }
-}
-
-# define COMPAT_INIT_WORK(_work, _func, _data) \
- INIT_LIST_HEAD(&(_work)->list); \
- (_work)->sync = 0; \
- (_work)->routine = _func; \
- (_work)->data = _data
-# define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \
- COMPAT_INIT_WORK(&(_work)->work, _func, _data); \
- init_timer(&(_work)->timer); \
- (_work)->timer.expires = 0; \
- (_work)->timer.function = __compat_delayed_work_timer; \
- (_work)->timer.data = (unsigned long)_work
-# define compat_schedule_work(_work) \
- schedule_task(_work)
-# define compat_schedule_delayed_work(_work, _delay) \
- (_work)->timer.expires = jiffies + _delay; \
- add_timer(&(_work)->timer)
-# define COMPAT_WORK_GET_DATA(_p, _type) \
- (_type *)(_p)
-# define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \
- (_type *)(_p)
-
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) /* } { */
-typedef struct work_struct compat_work;
-typedef struct work_struct compat_delayed_work;
-typedef void * compat_work_arg;
-typedef void * compat_delayed_work_arg;
-# define COMPAT_INIT_WORK(_work, _func, _data) \
- INIT_WORK(_work, _func, _data)
-# define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \
- INIT_WORK(_work, _func, _data)
-# define compat_schedule_work(_work) \
- schedule_work(_work)
-# define compat_schedule_delayed_work(_work, _delay) \
- schedule_delayed_work(_work, _delay)
-# define COMPAT_WORK_GET_DATA(_p, _type) \
- (_type *)(_p)
-# define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \
- (_type *)(_p)
-
-#else /* } Linux >= 2.6.20 { */
-typedef struct work_struct compat_work;
-typedef struct delayed_work compat_delayed_work;
-typedef struct work_struct * compat_work_arg;
-typedef struct work_struct * compat_delayed_work_arg;
-# define COMPAT_INIT_WORK(_work, _func, _data) \
- INIT_WORK(_work, _func)
-# define COMPAT_INIT_DELAYED_WORK(_work, _func, _data) \
- INIT_DELAYED_WORK(_work, _func)
-# define compat_schedule_work(_work) \
- schedule_work(_work)
-# define compat_schedule_delayed_work(_work, _delay) \
- schedule_delayed_work(_work, _delay)
-# define COMPAT_WORK_GET_DATA(_p, _type) \
- container_of(_p, _type, work)
-# define COMPAT_DELAYED_WORK_GET_DATA(_p, _type, _member) \
- container_of(_p, _type, _member.work)
-#endif /* } */
-
-#endif /* __COMPAT_WORKQUEUE_H__ */
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * Sets the proper defines from the Linux header files
- *
- * This file must be included before the inclusion of any kernel header file,
- * with the exception of linux/autoconf.h and linux/version.h --hpreg
- */
-
-#ifndef __VMX_CONFIG_H__
-#define __VMX_CONFIG_H__
-
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#include <linux/autoconf.h>
-#include "compat_version.h"
-
-/*
- * We rely on Kernel Module support. Check here.
- */
-#ifndef CONFIG_MODULES
-# error "No Module support in this kernel. Please configure with CONFIG_MODULES"
-#endif
-
-/*
- * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP
- * in the main Makefile), so we do it here.
- */
-
-#ifdef CONFIG_SMP
-# define __SMP__ 1
-#endif
-
-#if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-/*
- * MODVERSIONS might be already defined when using kernel's Makefiles.
- */
-# ifndef MODVERSIONS
-# define MODVERSIONS
-# endif
-# include <linux/modversions.h>
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-/*
- * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h.
- */
-# include <linux/types.h>
-# define _STDINT_H 1
-#endif
-
-#ifndef __KERNEL__
-# define __KERNEL__
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_assert.h --
- *
- * The basic assertion facility for all VMware code.
- *
- * For proper use, see
- * http://vmweb.vmware.com/~mts/WebSite/guide/programming/asserts.html
- */
-
-#ifndef _VM_ASSERT_H_
-#define _VM_ASSERT_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-// XXX not necessary except some places include vm_assert.h improperly
-#include "vm_basic_types.h"
-#include "vm_basic_defs.h"
-
-
-/*
- * XXX old file code
- */
-
-#ifdef FILECODEINT
-#error "Don't define FILECODEINT. It is obsolete."
-#endif
-#ifdef FILECODE
-#error "Don't define FILECODE. It is obsolete."
-#endif
-
-
-/*
- * Panic and log functions
- */
-
-EXTERN void Log(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN void Warning(const char *fmt, ...) PRINTF_DECL(1, 2);
-EXTERN NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2);
-
-EXTERN void LogThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-EXTERN void WarningThrottled(uint32 *count, const char *fmt, ...)
- PRINTF_DECL(2, 3);
-
-/* DB family: messages which are parsed by logfile database system */
-#define WarningDB Warning
-#define LogDB Log
-#define WarningThrottledDB WarningThrottled
-#define LogThrottledDB LogThrottled
-
-
-/*
- * Stress testing: redefine ASSERT_IFNOT() to taste
- */
-
-#ifndef ASSERT_IFNOT
- /*
- * PR 271512: When compiling with gcc, catch assignments inside an ASSERT.
- *
- * 'UNLIKELY' is defined with __builtin_expect, which does not warn when passed an
- * assignment (gcc bug 36050).
- * To get around this, we put 'cond' in an 'if' statement and make sure it never gets
- * executed by putting that inside of 'if (0)'.
- * We use gcc's statement expression syntax to make ASSERT an expression because some
- * code uses it that way.
- *
- * Since statement expression syntax is a gcc extension and since it's not clear if
- * this is a problem with other compilers, the ASSERT definition was not changed for
- * them. Using a bare 'cond' with the ternary operator may provide a solution.
- */
- #ifdef __GNUC__
- #define ASSERT_IFNOT(cond, panic) \
- ({if (UNLIKELY(!(cond))) { panic; if (0) { if (cond) { ; } } } (void)0;})
- #else
- #define ASSERT_IFNOT(cond, panic) \
- (UNLIKELY(!(cond)) ? (panic) : (void)0)
- #endif
-#endif
-
-
-/*
- * Assert, panic, and log macros
- *
- * Some of these are redefined below undef !VMX86_DEBUG.
- * ASSERT() is special cased because of interaction with Windows DDK.
- */
-
-#if defined VMX86_DEBUG || defined ASSERT_ALWAYS_AVAILABLE
-#undef ASSERT
-#define ASSERT(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertAssert))
-#endif
-#define ASSERT_BUG(bug, cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC_BUG(bug, AssertAssert))
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ASSERT_BUG(bug, cond)
-
-#define PANIC() _ASSERT_PANIC(AssertPanic)
-#define PANIC_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertPanic)
-
-#define ASSERT_NOT_IMPLEMENTED(cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED())
-#define ASSERT_NOT_IMPLEMENTED_BUG(bug, cond) \
- ASSERT_IFNOT(cond, NOT_IMPLEMENTED_BUG(bug))
-
-#define NOT_IMPLEMENTED() _ASSERT_PANIC(AssertNotImplemented)
-#define NOT_IMPLEMENTED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotImplemented)
-
-#define NOT_REACHED() _ASSERT_PANIC(AssertNotReached)
-#define NOT_REACHED_BUG(bug) _ASSERT_PANIC_BUG(bug, AssertNotReached)
-
-#define ASSERT_MEM_ALLOC(cond) \
- ASSERT_IFNOT(cond, _ASSERT_PANIC(AssertMemAlloc))
-
-#ifdef VMX86_DEVEL
- #define ASSERT_LENGTH(real, expected) \
- ASSERT_IFNOT((real) == (expected), \
- Panic(AssertLengthFmt, __FILE__, __LINE__, real, expected))
-#else
- #define ASSERT_LENGTH(real, expected) ASSERT((real) == (expected))
-#endif
-
-#ifdef VMX86_DEVEL
- #define ASSERT_DEVEL(cond) ASSERT(cond)
-#else
- #define ASSERT_DEVEL(cond) ((void) 0)
-#endif
-
-#define ASSERT_NO_INTERRUPTS() ASSERT(!INTERRUPTS_ENABLED())
-#define ASSERT_HAS_INTERRUPTS() ASSERT(INTERRUPTS_ENABLED())
-
-#define ASSERT_LOG_UNEXPECTED(bug, cond) \
- (UNLIKELY(!(cond)) ? LOG_UNEXPECTED(bug) : 0)
-#ifdef VMX86_DEVEL
- #define LOG_UNEXPECTED(bug) \
- Warning(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#else
- #define LOG_UNEXPECTED(bug) \
- Log(AssertUnexpectedFmt, __FILE__, __LINE__, bug)
-#endif
-
-#define ASSERT_NOT_TESTED(cond) (UNLIKELY(!(cond)) ? NOT_TESTED() : 0)
-#ifdef VMX86_DEVEL
- #define NOT_TESTED() Warning(AssertNotTestedFmt, __FILE__, __LINE__)
-#else
- #define NOT_TESTED() Log(AssertNotTestedFmt, __FILE__, __LINE__)
-#endif
-
-#define NOT_TESTED_ONCE() \
- do { \
- static Bool alreadyPrinted = FALSE; \
- if (UNLIKELY(!alreadyPrinted)) { \
- alreadyPrinted = TRUE; \
- NOT_TESTED(); \
- } \
- } while (0)
-
-#define NOT_TESTED_1024() \
- do { \
- static uint16 count = 0; \
- if (UNLIKELY(count == 0)) { NOT_TESTED(); } \
- count = (count + 1) & 1023; \
- } while (0)
-
-#define LOG_ONCE(_s) \
- do { \
- static Bool logged = FALSE; \
- if (!logged) { \
- Log _s; \
- logged = TRUE; \
- } \
- } while (0)
-
-
-/*
- * Redefine macros that are only in debug versions
- */
-
-#if !defined VMX86_DEBUG && !defined ASSERT_ALWAYS_AVAILABLE // {
-
-#undef ASSERT
-#define ASSERT(cond) ((void) 0)
-
-#undef ASSERT_BUG_DEBUGONLY
-#define ASSERT_BUG_DEBUGONLY(bug, cond) ((void) 0)
-
-#undef ASSERT_LENGTH
-#define ASSERT_LENGTH(real, expected) ((void) 0)
-
-/*
- * Expand NOT_REACHED() as appropriate for each situation.
- *
- * Mainly, we want the compiler to infer the same control-flow
- * information as it would from Panic(). Otherwise, different
- * compilation options will lead to different control-flow-derived
- * errors, causing some make targets to fail while others succeed.
- *
- * VC++ has the __assume() built-in function which we don't trust
- * (see bug 43485); gcc has no such construct; we just panic in
- * userlevel code. The monitor doesn't want to pay the size penalty
- * (measured at 212 bytes for the release vmm for a minimal infinite
- * loop; panic would cost even more) so it does without and lives
- * with the inconsistency.
- */
-
-#ifdef VMM
-#undef NOT_REACHED
-#define NOT_REACHED() ((void) 0)
-#else
-// keep debug definition
-#endif
-
-#undef ASSERT_LOG_UNEXPECTED
-#define ASSERT_LOG_UNEXPECTED(bug, cond) ((void) 0)
-
-#undef LOG_UNEXPECTED
-#define LOG_UNEXPECTED(bug) ((void) 0)
-
-#undef ASSERT_NOT_TESTED
-#define ASSERT_NOT_TESTED(cond) ((void) 0)
-#undef NOT_TESTED
-#define NOT_TESTED() ((void) 0)
-#undef NOT_TESTED_ONCE
-#define NOT_TESTED_ONCE() ((void) 0)
-#undef NOT_TESTED_1024
-#define NOT_TESTED_1024() ((void) 0)
-
-#endif // !VMX86_DEBUG }
-
-
-/*
- * Compile-time assertions.
- *
- * ASSERT_ON_COMPILE does not use the common
- * switch (0) { case 0: case (e): ; } trick because some compilers (e.g. MSVC)
- * generate code for it.
- *
- * The implementation uses both enum and typedef because the typedef alone is
- * insufficient; gcc allows arrays to be declared with non-constant expressions
- * (even in typedefs, where it makes no sense).
- */
-
-#define ASSERT_ON_COMPILE(e) \
- do { \
- enum { AssertOnCompileMisused = ((e) ? 1 : -1) }; \
- typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \
- } while (0)
-
-
-/*
- * To put an ASSERT_ON_COMPILE() outside a function, wrap it
- * in MY_ASSERTS(). The first parameter must be unique in
- * each .c file where it appears. For example,
- *
- * MY_ASSERTS(FS3_INT,
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLock) == 128);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskLockReserved) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(FS3_DiskBlock) == DISK_BLOCK_SIZE);
- * ASSERT_ON_COMPILE(sizeof(Hardware_DMIUUID) == 16);
- * )
- *
- * Caution: ASSERT() within MY_ASSERTS() is silently ignored.
- * The same goes for anything else not evaluated at compile time.
- */
-
-#define MY_ASSERTS(name, assertions) \
- static INLINE void name(void) { \
- assertions \
- }
-
-
-/*
- * Internal macros, functions, and strings
- *
- * The monitor wants to save space at call sites, so it has specialized
- * functions for each situation. User level wants to save on implementation
- * so it uses generic functions.
- */
-
-#if !defined VMM || defined MONITOR_APP // {
-
-#define _ASSERT_PANIC(name) \
- Panic(_##name##Fmt "\n", __FILE__, __LINE__)
-#define _ASSERT_PANIC_BUG(bug, name) \
- Panic(_##name##Fmt " bugNr=%d\n", __FILE__, __LINE__, bug)
-
-#define AssertLengthFmt _AssertLengthFmt
-#define AssertUnexpectedFmt _AssertUnexpectedFmt
-#define AssertNotTestedFmt _AssertNotTestedFmt
-
-#endif // }
-
-// these don't have newline so a bug can be tacked on
-#define _AssertPanicFmt "PANIC %s:%d"
-#define _AssertAssertFmt "ASSERT %s:%d"
-#define _AssertNotImplementedFmt "NOT_IMPLEMENTED %s:%d"
-#define _AssertNotReachedFmt "NOT_REACHED %s:%d"
-#define _AssertMemAllocFmt "MEM_ALLOC %s:%d"
-
-// these are complete formats with newline
-#define _AssertLengthFmt "LENGTH %s:%d r=%#x e=%#x\n"
-#define _AssertUnexpectedFmt "UNEXPECTED %s:%d bugNr=%d\n"
-#define _AssertNotTestedFmt "NOT_TESTED %s:%d\n"
-
-#endif /* ifndef _VM_ASSERT_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_atomic.h --
- *
- * Atomic power
- */
-
-#ifndef _ATOMIC_H_
-#define _ATOMIC_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-
-
-/* Basic atomic type: 32 bits */
-typedef struct Atomic_uint32 {
- volatile uint32 value;
-} Atomic_uint32;
-
-
-/* Basic atomic type: 64 bits */
-typedef struct Atomic_uint64 {
- volatile uint64 value;
-} Atomic_uint64 ALIGNED(8);
-
-
-/*
- * Prototypes for msft atomics. These are defined & inlined by the
- * compiler so no function definition is needed. The prototypes are
- * needed for c++. Since amd64 compiler doesn't support inline asm we
- * have to use these. Unfortunately, we still have to use some inline asm
- * for the 32 bit code since the and/or/xor implementations didn't show up
- * untill xp or 2k3.
- *
- * The declarations for the intrinsic functions were taken from ntddk.h
- * in the DDK. The declarations must match otherwise the 64-bit c++
- * compiler will complain about second linkage of the intrinsic functions.
- * We define the intrinsic using the basic types corresponding to the
- * Windows typedefs. This avoids having to include windows header files
- * to get to the windows types.
- */
-#if defined(_MSC_VER) && _MSC_VER >= 1310
-#ifdef __cplusplus
-extern "C" {
-#endif
-long _InterlockedExchange(long volatile*, long);
-long _InterlockedCompareExchange(long volatile*, long, long);
-long _InterlockedExchangeAdd(long volatile*, long);
-long _InterlockedDecrement(long volatile*);
-long _InterlockedIncrement(long volatile*);
-#pragma intrinsic(_InterlockedExchange, _InterlockedCompareExchange)
-#pragma intrinsic(_InterlockedExchangeAdd, _InterlockedDecrement)
-#pragma intrinsic(_InterlockedIncrement)
-
-#if defined(VM_X86_64)
-long _InterlockedAnd(long volatile*, long);
-__int64 _InterlockedAnd64(__int64 volatile*, __int64);
-long _InterlockedOr(long volatile*, long);
-__int64 _InterlockedOr64(__int64 volatile*, __int64);
-long _InterlockedXor(long volatile*, long);
-__int64 _InterlockedXor64(__int64 volatile*, __int64);
-__int64 _InterlockedExchangeAdd64(__int64 volatile*, __int64);
-__int64 _InterlockedIncrement64(__int64 volatile*);
-__int64 _InterlockedDecrement64(__int64 volatile*);
-__int64 _InterlockedExchange64(__int64 volatile*, __int64);
-__int64 _InterlockedCompareExchange64(__int64 volatile*, __int64, __int64);
-#if !defined(_WIN64)
-#pragma intrinsic(_InterlockedAnd, _InterlockedAnd64)
-#pragma intrinsic(_InterlockedOr, _InterlockedOr64)
-#pragma intrinsic(_InterlockedXor, _InterlockedXor64)
-#pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedIncrement64)
-#pragma intrinsic(_InterlockedDecrement64, _InterlockedExchange64)
-#pragma intrinsic(_InterlockedCompareExchange64)
-#endif /* !_WIN64 */
-#endif /* __x86_64__ */
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _MSC_VER */
-
-
-/* Convert a volatile int to Atomic_uint32. */
-static INLINE Atomic_uint32 *
-Atomic_VolatileToAtomic(volatile uint32 *var)
-{
- return (Atomic_uint32 *)var;
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Init, Atomic_SetFence, AtomicUseFence --
- *
- * Determine whether an lfence intruction is executed after
- * every locked instruction.
- *
- * Certain AMD processes have a bug (see bug 107024) that
- * requires an lfence after every locked instruction.
- *
- * The global variable AtomicUseFence controls whether lfence
- * is used (see AtomicEpilogue).
- *
- * Atomic_SetFence sets AtomicUseFence to the given value.
- *
- * Atomic_Init computes and sets AtomicUseFence.
- * It does not take into account the number of processors.
- *
- * The rationale for all this complexity is that Atomic_Init
- * is the easy-to-use interface. It can be called a number
- * of times cheaply, and does not depend on other libraries.
- * However, because the number of CPUs is difficult to compute,
- * it does without it and always assumes there are more than one.
- *
- * For programs that care or have special requirements,
- * Atomic_SetFence can be called directly, in addition to Atomic_Init.
- * It overrides the effect of Atomic_Init, and can be called
- * before, after, or between calls to Atomic_Init.
- *
- *-----------------------------------------------------------------------------
- */
-
-// The freebsd assembler doesn't know the lfence instruction
-#if defined(__GNUC__) && \
- __GNUC__ >= 3 && \
- (defined(__VMKERNEL__) || !defined(__FreeBSD__)) && \
- (!defined(MODULE) || defined(__VMKERNEL_MODULE__)) && \
- !defined(__APPLE__) /* PR136775 */
-#define ATOMIC_USE_FENCE
-#endif
-
-#if defined(VMATOMIC_IMPORT_DLLDATA)
-VMX86_EXTERN_DATA Bool AtomicUseFence;
-#else
-EXTERN Bool AtomicUseFence;
-#endif
-
-EXTERN Bool atomicFenceInitialized;
-
-void AtomicInitFence(void);
-
-static INLINE void
-Atomic_Init(void)
-{
-#ifdef ATOMIC_USE_FENCE
- if (!atomicFenceInitialized) {
- AtomicInitFence();
- }
-#endif
-}
-
-static INLINE void
-Atomic_SetFence(Bool fenceAfterLock) /* IN: TRUE to enable lfence */
- /* FALSE to disable. */
-{
- AtomicUseFence = fenceAfterLock;
-#if defined(__VMKERNEL__)
- extern void Atomic_SetFenceVMKAPI(Bool fenceAfterLock);
- Atomic_SetFenceVMKAPI(fenceAfterLock);
-#endif
- atomicFenceInitialized = TRUE;
-}
-
-
-/* Conditionally execute fence after interlocked instruction. */
-static INLINE void
-AtomicEpilogue(void)
-{
-#ifdef ATOMIC_USE_FENCE
-#ifdef VMM
- /* The monitor conditionally patches out the lfence when not needed.*/
- /* Construct a MonitorPatchTextEntry in the .patchtext section. */
- asm volatile ("1:\n\t"
- "lfence\n\t"
- "2:\n\t"
- ".pushsection .patchtext\n\t"
-#ifdef VMM32
- ".long 1b\n\t"
- ".long 0\n\t"
- ".long 2b\n\t"
- ".long 0\n\t"
-#else
- ".quad 1b\n\t"
- ".quad 2b\n\t"
-#endif
- ".popsection\n\t" ::: "memory");
-#else
- if (UNLIKELY(AtomicUseFence)) {
- asm volatile ("lfence" ::: "memory");
- }
-#endif
-#endif
-}
-
-
-/*
- * All the assembly code is tricky and written conservatively.
- * For example, to make sure gcc won't introduce copies,
- * we force the addressing mode like this:
- *
- * "xchgl %0, (%1)"
- * : "=r" (val)
- * : "r" (&var->value),
- * "0" (val)
- * : "memory"
- *
- * - edward
- *
- * Actually - turns out that gcc never generates memory aliases (it
- * still does generate register aliases though), so we can be a bit
- * more agressive with the memory constraints. The code above can be
- * modified like this:
- *
- * "xchgl %0, %1"
- * : "=r" (val),
- * "=m" (var->value),
- * : "0" (val),
- * "1" (var->value)
- *
- * The advantages are that gcc can use whatever addressing mode it
- * likes to access the memory value, and that we dont have to use a
- * way-too-generic "memory" clobber as there is now an explicit
- * declaration that var->value is modified.
- *
- * see also /usr/include/asm/atomic.h to convince yourself this is a
- * valid optimization.
- *
- * - walken
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Read --
- *
- * Read
- *
- * Results:
- * The value of the atomic variable.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_Read(Atomic_uint32 const *var) // IN
-{
- return var->value;
-}
-#define Atomic_Read32 Atomic_Read
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Write --
- *
- * Write
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Write(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
- var->value = val;
-}
-#define Atomic_Write32 Atomic_Write
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadWrite --
- *
- * Read followed by write
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_ReadWrite(Atomic_uint32 *var, // IN
- uint32 val) // IN
-#ifdef __GNUC__
-{
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "xchgl %0, %1"
-# if VM_ASM_PLUS
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
-# else
- : "=r" (val),
- "=m" (var->value)
- : "0" (val),
- "1" (var->value)
-# endif
- );
- AtomicEpilogue();
- return val;
-}
-#elif _MSC_VER >= 1310
-{
- return _InterlockedExchange((long *)&var->value, (long)val);
-}
-#elif _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov eax, val
- __asm mov ebx, var
- __asm xchg [ebx]Atomic_uint32.value, eax
- // eax is the return value, this is documented to work - edward
-}
-#pragma warning(pop)
-#else
-#error No compiler defined for Atomic_ReadWrite
-#endif
-#define Atomic_ReadWrite32 Atomic_ReadWrite
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadIfEqualWrite --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * The variable may be modified.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_ReadIfEqualWrite(Atomic_uint32 *var, // IN
- uint32 oldVal, // IN
- uint32 newVal) // IN
-#ifdef __GNUC__
-{
- uint32 val;
-
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; cmpxchgl %2, %1"
-# if VM_ASM_PLUS
- : "=a" (val),
- "+m" (var->value)
- : "r" (newVal),
- "0" (oldVal)
-# else
- : "=a" (val),
- "=m" (var->value)
- : "r" (newVal),
- "0" (oldVal)
- /*
- * "1" (var->value): results in inconsistent constraints on gcc 2.7.2.3
- * when compiling enterprise-2.2.17-14-RH7.0-update.
- * The constraint has been commented out for now. We may consider doing
- * this systematically, but we need to be sure it is the right thing to
- * do. However, it is also possible that the offending use of this asm
- * function will be removed in the near future in which case we may
- * decide to reintroduce the constraint instead. hpreg & agesen.
- */
-# endif
- : "cc"
- );
- AtomicEpilogue();
- return val;
-}
-#elif _MSC_VER >= 1310
-{
- return _InterlockedCompareExchange((long *)&var->value,
- (long)newVal,
- (long)oldVal);
-}
-#elif _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov eax, oldVal
- __asm mov ebx, var
- __asm mov ecx, newVal
- __asm lock cmpxchg [ebx]Atomic_uint32.value, ecx
- // eax is the return value, this is documented to work - edward
-}
-#pragma warning(pop)
-#else
-#error No compiler defined for Atomic_ReadIfEqualWrite
-#endif
-#define Atomic_ReadIfEqualWrite32 Atomic_ReadIfEqualWrite
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadIfEqualWrite64 --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * The variable may be modified.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadIfEqualWrite64(Atomic_uint64 *var, // IN
- uint64 oldVal, // IN
- uint64 newVal) // IN
-{
-#if defined(__GNUC__)
- uint64 val;
-
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; cmpxchgq %2, %1"
- : "=a" (val),
- "+m" (var->value)
- : "r" (newVal),
- "0" (oldVal)
- : "cc"
- );
- AtomicEpilogue();
- return val;
-#elif _MSC_VER
- return _InterlockedCompareExchange64((__int64 *)&var->value,
- (__int64)newVal,
- (__int64)oldVal);
-#else
-#error No compiler defined for Atomic_ReadIfEqualWrite64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_And --
- *
- * Atomic read, bitwise AND with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_And(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; andl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
-#if defined(__x86_64__)
- _InterlockedAnd((long *)&var->value, (long)val);
-#else
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock and [ebx]Atomic_uint32.value, eax
-#endif
-#else
-#error No compiler defined for Atomic_And
-#endif
-}
-#define Atomic_And32 Atomic_And
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_And64 --
- *
- * Atomic read, bitwise AND with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_And64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; andq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedAnd64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_And64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Or --
- *
- * Atomic read, bitwise OR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Or(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; orl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
-#if defined(__x86_64__)
- _InterlockedOr((long *)&var->value, (long)val);
-#else
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock or [ebx]Atomic_uint32.value, eax
-#endif
-#else
-#error No compiler defined for Atomic_Or
-#endif
-}
-#define Atomic_Or32 Atomic_Or
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Or64 --
- *
- * Atomic read, bitwise OR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Or64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; orq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedOr64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_Or64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Xor --
- *
- * Atomic read, bitwise XOR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Xor(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; xorl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
-#if defined(__x86_64__)
- _InterlockedXor((long *)&var->value, (long)val);
-#else
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock xor [ebx]Atomic_uint32.value, eax
-#endif
-#else
-#error No compiler defined for Atomic_Xor
-#endif
-}
-#define Atomic_Xor32 Atomic_Xor
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Xor64 --
- *
- * Atomic read, bitwise XOR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Xor64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; xorq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedXor64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_Xor64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Add --
- *
- * Atomic read, add a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Add(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; addl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedExchangeAdd((long *)&var->value, (long)val);
-#elif _MSC_VER
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock add [ebx]Atomic_uint32.value, eax
-#else
-#error No compiler defined for Atomic_Add
-#endif
-}
-#define Atomic_Add32 Atomic_Add
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Add64 --
- *
- * Atomic read, add a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Add64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; addq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_Add64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Sub --
- *
- * Atomic read, subtract a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Sub(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; subl %1, %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- : "ri" (val)
-# else
- : "=m" (var->value)
- : "ri" (val),
- "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedExchangeAdd((long *)&var->value, (long)-val);
-#elif _MSC_VER
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock sub [ebx]Atomic_uint32.value, eax
-#else
-#error No compiler defined for Atomic_Sub
-#endif
-}
-#define Atomic_Sub32 Atomic_Sub
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Sub64 --
- *
- * Atomic read, subtract a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Sub64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#ifdef __GNUC__
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; subq %1, %0"
- : "+m" (var->value)
- : "ri" (val)
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)-val);
-#else
-#error No compiler defined for Atomic_Sub64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Inc --
- *
- * Atomic read, increment, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Inc(Atomic_uint32 *var) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; incl %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- :
-# else
- : "=m" (var->value)
- : "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedIncrement((long *)&var->value);
-#elif _MSC_VER
- __asm mov ebx, var
- __asm lock inc [ebx]Atomic_uint32.value
-#else
-#error No compiler defined for Atomic_Inc
-#endif
-}
-#define Atomic_Inc32 Atomic_Inc
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Inc64 --
- *
- * Atomic read, increment, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Inc64(Atomic_uint64 *var) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; incq %0"
- : "+m" (var->value)
- :
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedIncrement64((__int64 *)&var->value);
-#else
-#error No compiler defined for Atomic_Inc64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Dec --
- *
- * Atomic read, decrement, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Dec(Atomic_uint32 *var) // IN
-{
-#ifdef __GNUC__
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
- "lock; decl %0"
-# if VM_ASM_PLUS
- : "+m" (var->value)
- :
-# else
- : "=m" (var->value)
- : "0" (var->value)
-# endif
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER >= 1310
- _InterlockedDecrement((long *)&var->value);
-#elif _MSC_VER
- __asm mov ebx, var
- __asm lock dec [ebx]Atomic_uint32.value
-#else
-#error No compiler defined for Atomic_Dec
-#endif
-}
-#define Atomic_Dec32 Atomic_Dec
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Dec64 --
- *
- * Atomic read, decrement, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Dec64(Atomic_uint64 *var) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; decq %0"
- : "+m" (var->value)
- :
- : "cc"
- );
- AtomicEpilogue();
-#elif _MSC_VER
- _InterlockedDecrement64((__int64 *)&var->value);
-#else
-#error No compiler defined for Atomic_Dec64
-#endif
-}
-#endif
-
-
-/*
- * Note that the technique below can be used to implement ReadX(), where X is
- * an arbitrary mathematical function.
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndOr --
- *
- * Atomic read (returned), bitwise OR with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndOr(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
- uint32 res;
-
- do {
- res = var->value;
- } while (res != Atomic_ReadIfEqualWrite(var, res, res | val));
-
- return res;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndAnd --
- *
- * Atomic read (returned), bitwise And with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndAnd(Atomic_uint32 *var, // IN
- uint32 val) // IN
-{
- uint32 res;
-
- do {
- res = var->value;
- } while (res != Atomic_ReadIfEqualWrite(var, res, res & val));
-
- return res;
-}
-#define Atomic_ReadOr32 Atomic_FetchAndOr
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadOr64 --
- *
- * Atomic read (returned), bitwise OR with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadOr64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
- uint64 res;
-
- do {
- res = var->value;
- } while (res != Atomic_ReadIfEqualWrite64(var, res, res | val));
-
- return res;
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndAddUnfenced --
- *
- * Atomic read (returned), add a value, write.
- *
- * If you have to implement FetchAndAdd() on an architecture other than
- * x86 or x86-64, you might want to consider doing something similar to
- * Atomic_FetchAndOr().
- *
- * The "Unfenced" version of Atomic_FetchAndInc never executes
- * "lfence" after the interlocked operation.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndAddUnfenced(Atomic_uint32 *var, // IN
- uint32 val) // IN
-#ifdef __GNUC__
-{
- /* Checked against the Intel manual and GCC --walken */
- __asm__ __volatile__(
-# if VM_ASM_PLUS
- "lock; xaddl %0, %1"
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
- : "cc"
-# else
- "lock; xaddl %0, (%1)"
- : "=r" (val)
- : "r" (&var->value),
- "0" (val)
- : "cc", "memory"
-# endif
- );
- return val;
-}
-#elif _MSC_VER >= 1310
-{
- return _InterlockedExchangeAdd((long *)&var->value, (long)val);
-}
-#elif _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov eax, val
- __asm mov ebx, var
- __asm lock xadd [ebx]Atomic_uint32.value, eax
-}
-#pragma warning(pop)
-#else
-#error No compiler defined for Atomic_FetchAndAdd
-#endif
-#define Atomic_ReadAdd32 Atomic_FetchAndAdd
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndAdd --
- *
- * Atomic read (returned), add a value, write.
- *
- * If you have to implement FetchAndAdd() on an architecture other than
- * x86 or x86-64, you might want to consider doing something similar to
- * Atomic_FetchAndOr().
- *
- * Unlike "Unfenced" version, this one may execute the "lfence" after
- * interlocked operation.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndAdd(Atomic_uint32 *var, // IN
- uint32 val) // IN
-#ifdef __GNUC__
-{
- val = Atomic_FetchAndAddUnfenced(var, val);
- AtomicEpilogue();
- return val;
-}
-#else
-{
- return Atomic_FetchAndAddUnfenced(var, val);
-}
-#endif
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadAdd64 --
- *
- * Atomic read (returned), add a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadAdd64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "lock; xaddq %0, %1"
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
- : "cc"
- );
- AtomicEpilogue();
- return val;
-#elif _MSC_VER
- return _InterlockedExchangeAdd64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_ReadAdd64
-#endif
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndInc --
- *
- * Atomic read (returned), increment, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndInc(Atomic_uint32 *var) // IN
-{
- return Atomic_FetchAndAdd(var, 1);
-}
-#define Atomic_ReadInc32 Atomic_FetchAndInc
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadInc64 --
- *
- * Atomic read (returned), increment, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadInc64(Atomic_uint64 *var) // IN
-{
- return Atomic_ReadAdd64(var, 1);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_FetchAndDec --
- *
- * Atomic read (returned), decrement, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Atomic_FetchAndDec(Atomic_uint32 *var) // IN
-{
- return Atomic_FetchAndAdd(var, (uint32)-1);
-}
-#define Atomic_ReadDec32 Atomic_FetchAndDec
-
-
-#if defined(__x86_64__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadDec64 --
- *
- * Atomic read (returned), decrement, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadDec64(Atomic_uint64 *var) // IN
-{
- return Atomic_ReadAdd64(var, CONST64U(-1));
-}
-#endif
-
-
-#ifdef VMKERNEL
-/*
- *-----------------------------------------------------------------------------
- *
- * CMPXCHG1B --
- *
- * Compare and exchange a single byte.
- *
- * Results:
- * The value read from ptr.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-static INLINE uint8
-CMPXCHG1B(volatile uint8 *ptr, // IN
- uint8 oldVal, // IN
- uint8 newVal) // IN
-{
- uint8 val;
- __asm__ __volatile__("lock; cmpxchgb %b2, %1"
- : "=a" (val),
- "+m" (*ptr)
- : "r" (newVal),
- "0" (oldVal)
- : "cc");
- return val;
-}
-#endif
-
-
-/*
- * Usage of this helper struct is strictly reserved to the following
- * function. --hpreg
- */
-typedef struct {
- uint32 lowValue;
- uint32 highValue;
-} S_uint64;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_CMPXCHG64 --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * XXX: Ensure that if this function is to be inlined by gcc, it is
- * compiled with -fno-strict-aliasing. Otherwise it will break.
- * Unfortunately we know that gcc 2.95.3 (used to build the FreeBSD 3.2
- * Tools) does not honor -fno-strict-aliasing. As a workaround, we avoid
- * inlining the function entirely for versions of gcc under 3.0.
- *
- * Results:
- * TRUE if equal, FALSE if not equal
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__) && __GNUC__ < 3
-static Bool
-#else
-static INLINE Bool
-#endif
-Atomic_CMPXCHG64(Atomic_uint64 *var, // IN/OUT
- uint64 const *oldVal, // IN
- uint64 const *newVal) // IN
-#ifdef __GNUC__
-{
- Bool equal;
-
- /* Checked against the Intel manual and GCC --walken */
-#ifdef VMM64
- uint64 dummy;
- __asm__ __volatile__(
- "lock; cmpxchgq %3, %0" "\n\t"
- "sete %1"
- : "+m" (*var),
- "=qm" (equal),
- "=a" (dummy)
- : "r" (*newVal),
- "2" (*oldVal)
- : "cc"
- );
-#else /* 32-bit version */
- int dummy1, dummy2;
-# if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
-# if defined __GNUC__ && __GNUC__ < 3 // Part of #188541 - for RHL 6.2 etc.
- __asm__ __volatile__(
- "xchg %%ebx, %6\n\t"
- "mov (%%ebx), %%ecx\n\t"
- "mov (%%ebx), %%ebx\n\t"
- "lock; cmpxchg8b (%3)\n\t"
- "xchg %%ebx, %6\n\t"
- "sete %0"
- : "=a" (equal), "=d" (dummy2), "=D" (dummy1)
- : "S" (var), "0" (((S_uint64 const *)oldVal)->lowValue),
- "1" (((S_uint64 const *)oldVal)->highValue), "D" (newVal)
- : "ecx", "cc", "memory"
- );
-# else
- __asm__ __volatile__(
- "xchgl %%ebx, %6" "\n\t"
- // %3 is a register to make sure it cannot be %ebx-relative.
- "lock; cmpxchg8b (%3)" "\n\t"
- "xchgl %%ebx, %6" "\n\t"
- // Must come after restoring %ebx: %0 could be %ebx-relative.
- "sete %0"
- : "=qm" (equal),
- "=a" (dummy1),
- "=d" (dummy2)
- : "r" (var),
- "1" (((S_uint64 const *)oldVal)->lowValue),
- "2" (((S_uint64 const *)oldVal)->highValue),
- // Cannot use "m" here: 'newVal' is read-only.
- "r" (((S_uint64 const *)newVal)->lowValue),
- "c" (((S_uint64 const *)newVal)->highValue)
- : "cc", "memory"
- );
-# endif
-# else
- __asm__ __volatile__(
- "lock; cmpxchg8b %0" "\n\t"
- "sete %1"
-# if VM_ASM_PLUS
- : "+m" (*var),
-# else
- : "=m" (*var),
-# endif
- "=qm" (equal),
- "=a" (dummy1),
- "=d" (dummy2)
- : "2" (((S_uint64 const *)oldVal)->lowValue),
- "3" (((S_uint64 const *)oldVal)->highValue),
- "b" (((S_uint64 const *)newVal)->lowValue),
- "c" (((S_uint64 const *)newVal)->highValue)
- : "cc"
- );
-# endif
-#endif
- AtomicEpilogue();
- return equal;
-}
-#elif _MSC_VER
-#if defined(__x86_64__)
-{
- return *oldVal == _InterlockedCompareExchange64((__int64 *)&var->value,
- (__int64)*newVal,
- (__int64)*oldVal);
-}
-#else
-#pragma warning(push)
-#pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov esi, var
- __asm mov edx, oldVal
- __asm mov ecx, newVal
- __asm mov eax, [edx]S_uint64.lowValue
- __asm mov edx, [edx]S_uint64.highValue
- __asm mov ebx, [ecx]S_uint64.lowValue
- __asm mov ecx, [ecx]S_uint64.highValue
- __asm lock cmpxchg8b [esi]
- __asm sete al
- __asm movzx eax, al
- // eax is the return value, this is documented to work - edward
-}
-#pragma warning(pop)
-#endif
-#else
-#error No compiler defined for Atomic_CMPXCHG64
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_CMPXCHG32 --
- *
- * Compare exchange: Read variable, if equal to oldVal, write newVal
- *
- * Results:
- * TRUE if equal, FALSE if not equal
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-Atomic_CMPXCHG32(Atomic_uint32 *var, // IN/OUT
- uint32 oldVal, // IN
- uint32 newVal) // IN
-{
-#ifdef __GNUC__
- Bool equal;
-
- uint32 dummy;
- __asm__ __volatile__(
- "lock; cmpxchgl %3, %0" "\n\t"
- "sete %1"
-# if VM_ASM_PLUS
- : "+m" (*var),
- "=qm" (equal),
- "=a" (dummy)
- : "r" (newVal),
- "2" (oldVal)
-# else
- : "=m" (*var),
- "=qm" (equal),
- "=a" (dummy)
- : /*"0" (*var), */
- "r" (newVal),
- "2" (oldVal)
-# endif
- : "cc"
- );
- AtomicEpilogue();
- return equal;
-#else
- return (Atomic_ReadIfEqualWrite(var, oldVal, newVal) == oldVal);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Read64 --
- *
- * Read and return.
- *
- * Results:
- * The value of the atomic variable.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_Read64(Atomic_uint64 const *var) // IN
-#if defined(__x86_64__)
-{
- return var->value;
-}
-#elif defined(__GNUC__) && defined(__i386__) /* GCC on x86 */
-{
- uint64 value;
- /*
- * Since cmpxchg8b will replace the contents of EDX:EAX with the
- * value in memory if there is no match, we need only execute the
- * instruction once in order to atomically read 64 bits from
- * memory. The only constraint is that ECX:EBX must have the same
- * value as EDX:EAX so that if the comparison succeeds. We
- * intentionally don't tell gcc that we are using ebx and ecx as we
- * don't modify them and do not care what value they store.
- */
- __asm__ __volatile__(
- "mov %%ebx, %%eax" "\n\t"
- "mov %%ecx, %%edx" "\n\t"
- "lock; cmpxchg8b %1"
- : "=&A" (value)
- : "m" (*var)
- : "cc"
- );
- AtomicEpilogue();
- return value;
-}
-#elif _MSC_VER /* MSC (assume on x86 for now) */
-# pragma warning(push)
-# pragma warning(disable : 4035) // disable no-return warning
-{
- __asm mov ecx, var
- __asm mov edx, ecx
- __asm mov eax, ebx
- __asm lock cmpxchg8b [ecx]
- // edx:eax is the return value; this is documented to work. --mann
-}
-# pragma warning(pop)
-#else
-# error No compiler defined for Atomic_Read64
-#endif
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Atomic_FetchAndAdd64 --
- *
- * Atomically adds a 64-bit integer to another
- *
- * Results:
- * Returns the old value just prior to the addition
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_FetchAndAdd64(Atomic_uint64 *var, // IN/OUT
- uint64 addend) // IN
-{
- uint64 oldVal;
- uint64 newVal;
-
- do {
- oldVal = var->value;
- newVal = oldVal + addend;
- } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal));
-
- return oldVal;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Atomic_FetchAndInc64 --
- *
- * Atomically increments a 64-bit integer
- *
- * Results:
- * Returns the old value just prior to incrementing
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_FetchAndInc64(Atomic_uint64 *var) // IN/OUT
-{
- return Atomic_FetchAndAdd64(var, 1);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Atomic_FetchAndDec64 --
- *
- * Atomically decrements a 64-bit integer
- *
- * Results:
- * Returns the old value just prior to decrementing
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_FetchAndDec64(Atomic_uint64 *var) // IN/OUT
-{
- uint64 oldVal;
- uint64 newVal;
-
- do {
- oldVal = var->value;
- newVal = oldVal - 1;
- } while (!Atomic_CMPXCHG64(var, &oldVal, &newVal));
-
- return oldVal;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadWrite64 --
- *
- * Read followed by write
- *
- * Results:
- * The value of the atomic variable before the write.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Atomic_ReadWrite64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__x86_64__)
-#if defined(__GNUC__)
- /* Checked against the AMD manual and GCC --hpreg */
- __asm__ __volatile__(
- "xchgq %0, %1"
- : "=r" (val),
- "+m" (var->value)
- : "0" (val)
- );
- AtomicEpilogue();
- return val;
-#elif _MSC_VER
- return _InterlockedExchange64((__int64 *)&var->value, (__int64)val);
-#else
-#error No compiler defined for Atomic_ReadWrite64
-#endif
-#else
- uint64 oldVal;
-
- do {
- oldVal = var->value;
- } while (!Atomic_CMPXCHG64(var, &oldVal, &val));
-
- return oldVal;
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Write64 --
- *
- * Write
- *
- * Results:
- * None.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Write64(Atomic_uint64 *var, // IN
- uint64 val) // IN
-{
-#if defined(__x86_64__)
- var->value = val;
-#else
- (void)Atomic_ReadWrite64(var, val);
-#endif
-}
-
-
-/*
- * Template code for the Atomic_<name> type and its operators.
- *
- * The cast argument is an intermedia type cast to make some
- * compilers stop complaining about casting uint32 <-> void *,
- * even though we only do it in the 32-bit case so they are always
- * the same size. So for val of type uint32, instead of
- * (void *)val, we have (void *)(uintptr_t)val.
- * The specific problem case is the Windows ddk compiler
- * (as used by the SVGA driver). -- edward
- */
-
-#define MAKE_ATOMIC_TYPE(name, size, in, out, cast) \
- typedef Atomic_uint ## size Atomic_ ## name; \
- \
- \
- static INLINE out \
- Atomic_Read ## name(Atomic_ ## name const *var) \
- { \
- return (out)(cast)Atomic_Read ## size(var); \
- } \
- \
- \
- static INLINE void \
- Atomic_Write ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Write ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadWrite ## name(Atomic_ ## name *var, \
- in val) \
- { \
- return (out)(cast)Atomic_ReadWrite ## size(var, \
- (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadIfEqualWrite ## name(Atomic_ ## name *var, \
- in oldVal, \
- in newVal) \
- { \
- return (out)(cast)Atomic_ReadIfEqualWrite ## size(var, \
- (uint ## size)(cast)oldVal, (uint ## size)(cast)newVal); \
- } \
- \
- \
- static INLINE void \
- Atomic_And ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_And ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Or ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Or ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Xor ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Xor ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Add ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Add ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Sub ## name(Atomic_ ## name *var, \
- in val) \
- { \
- Atomic_Sub ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE void \
- Atomic_Inc ## name(Atomic_ ## name *var) \
- { \
- Atomic_Inc ## size(var); \
- } \
- \
- \
- static INLINE void \
- Atomic_Dec ## name(Atomic_ ## name *var) \
- { \
- Atomic_Dec ## size(var); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadOr ## name(Atomic_ ## name *var, \
- in val) \
- { \
- return (out)(cast)Atomic_ReadOr ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadAdd ## name(Atomic_ ## name *var, \
- in val) \
- { \
- return (out)(cast)Atomic_ReadAdd ## size(var, (uint ## size)(cast)val); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadInc ## name(Atomic_ ## name *var) \
- { \
- return (out)(cast)Atomic_ReadInc ## size(var); \
- } \
- \
- \
- static INLINE out \
- Atomic_ReadDec ## name(Atomic_ ## name *var) \
- { \
- return (out)(cast)Atomic_ReadDec ## size(var); \
- }
-
-
-/*
- * Since we use a macro to generate these definitions, it is hard to look for
- * them. So DO NOT REMOVE THIS COMMENT and keep it up-to-date. --hpreg
- *
- * Atomic_Ptr
- * Atomic_ReadPtr --
- * Atomic_WritePtr --
- * Atomic_ReadWritePtr --
- * Atomic_ReadIfEqualWritePtr --
- * Atomic_AndPtr --
- * Atomic_OrPtr --
- * Atomic_XorPtr --
- * Atomic_AddPtr --
- * Atomic_SubPtr --
- * Atomic_IncPtr --
- * Atomic_DecPtr --
- * Atomic_ReadOrPtr --
- * Atomic_ReadAddPtr --
- * Atomic_ReadIncPtr --
- * Atomic_ReadDecPtr --
- *
- * Atomic_Int
- * Atomic_ReadInt --
- * Atomic_WriteInt --
- * Atomic_ReadWriteInt --
- * Atomic_ReadIfEqualWriteInt --
- * Atomic_AndInt --
- * Atomic_OrInt --
- * Atomic_XorInt --
- * Atomic_AddInt --
- * Atomic_SubInt --
- * Atomic_IncInt --
- * Atomic_DecInt --
- * Atomic_ReadOrInt --
- * Atomic_ReadAddInt --
- * Atomic_ReadIncInt --
- * Atomic_ReadDecInt --
- */
-#if defined(__x86_64__)
-MAKE_ATOMIC_TYPE(Ptr, 64, void const *, void *, uintptr_t)
-MAKE_ATOMIC_TYPE(Int, 64, int, int, int)
-#else
-MAKE_ATOMIC_TYPE(Ptr, 32, void const *, void *, uintptr_t)
-MAKE_ATOMIC_TYPE(Int, 32, int, int, int)
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_MFence --
- *
- * Implements mfence in terms of a lock xor. The reason for implementing
- * our own mfence is that not all of our supported cpus have an assembly
- * mfence (P3, Athlon). We put it here to avoid duplicating code which is
- * also why it is prefixed with "Atomic_".
- *
- * Results:
- * None.
- *
- * Side effects:
- * Cause loads and stores prior to this to be globally
- * visible.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_MFence(void)
-{
- Atomic_uint32 fence;
- Atomic_Xor(&fence, 0x1);
-}
-
-#endif // ifndef _ATOMIC_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_asm.h
- *
- * Basic asm macros
- */
-
-#ifndef _VM_BASIC_ASM_H_
-#define _VM_BASIC_ASM_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-#include "x86cpuid.h"
-
-#ifdef VM_X86_64
-#include "vm_basic_asm_x86_64.h"
-#else
-#include "vm_basic_asm_x86.h"
-#endif
-
-
-/*
- * x86-64 windows doesn't support inline asm so we have to use these
- * intrinsic functions defined in the compiler. Not all of these are well
- * documented. There is an array in the compiler dll (c1.dll) which has
- * an array of the names of all the intrinsics minus the leading
- * underscore. Searching around in the ntddk.h file can also be helpful.
- *
- * The declarations for the intrinsic functions were taken from the DDK.
- * Our declarations must match the ddk's otherwise the 64-bit c++ compiler
- * will complain about second linkage of the intrinsic functions.
- * We define the intrinsic using the basic types corresponding to the
- * Windows typedefs. This avoids having to include windows header files
- * to get to the windows types.
- */
-#ifdef _MSC_VER
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * It seems x86 & x86-64 windows still implements these intrinsic
- * functions. The documentation for the x86-64 suggest the
- * __inbyte/__outbyte intrinsics eventhough the _in/_out work fine and
- * __inbyte/__outbyte aren't supported on x86.
- */
-int _inp(unsigned short);
-unsigned short _inpw(unsigned short);
-unsigned long _inpd(unsigned short);
-
-int _outp(unsigned short, int);
-unsigned short _outpw(unsigned short, unsigned short);
-unsigned long _outpd(uint16, unsigned long);
-#pragma intrinsic(_inp, _inpw, _inpd, _outp, _outpw, _outpw, _outpd)
-void _ReadWriteBarrier(void);
-#pragma intrinsic(_ReadWriteBarrier)
-
-#ifdef VM_X86_64
-/*
- * intrinsic functions only supported by x86-64 windows as of 2k3sp1
- */
-void __cpuid(unsigned int*, unsigned int);
-unsigned __int64 __rdtsc(void);
-void __stosw(unsigned short*, unsigned short, size_t);
-void __stosd(unsigned long*, unsigned long, size_t);
-#pragma intrinsic(__cpuid, __rdtsc, __stosw, __stosd)
-
-/*
- * intrinsic functions supported by x86-64 windows and newer x86
- * compilers (13.01.2035 for _BitScanForward).
- */
-unsigned char _BitScanForward(unsigned long*, unsigned long);
-void _mm_pause(void);
-#pragma intrinsic(_BitScanForward, _mm_pause)
-#endif /* VM_X86_64 */
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _MSC_VER */
-
-
-#ifdef __GNUC__ // {
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * volatile because reading from port can modify the state of the underlying
- * hardware.
- *
- * Note: The undocumented %z construct doesn't work (internal compiler error)
- * with gcc-2.95.1
- */
-
-#define __GCC_IN(s, type, name) \
-static INLINE type \
-name(uint16 port) \
-{ \
- type val; \
- \
- __asm__ __volatile__( \
- "in" #s " %w1, %0" \
- : "=a" (val) \
- : "Nd" (port) \
- ); \
- \
- return val; \
-}
-
-__GCC_IN(b, uint8, INB)
-__GCC_IN(w, uint16, INW)
-__GCC_IN(l, uint32, IN32)
-
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * Note: The undocumented %z construct doesn't work (internal compiler error)
- * with gcc-2.95.1
- */
-
-#define __GCC_OUT(s, s2, port, val) do { \
- __asm__( \
- "out" #s " %" #s2 "1, %w0" \
- : \
- : "Nd" (port), "a" (val) \
- ); \
-} while (0)
-
-#define OUTB(port, val) __GCC_OUT(b, b, port, val)
-#define OUTW(port, val) __GCC_OUT(w, w, port, val)
-#define OUT32(port, val) __GCC_OUT(l, , port, val)
-
-
-#define GET_CURRENT_EIP(_eip) \
- __asm__ __volatile("call 0\n\tpopl %0" : "=r" (_eip): );
-
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * Need __volatile__ and "memory" since CPUID has a synchronizing effect.
- * The CPUID may also change at runtime (APIC flag, etc).
- *
- */
-
-static INLINE void
-__GET_CPUID(int eax, // IN
- CPUIDRegs *regs) // OUT
-{
- __asm__ __volatile__(
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (regs->eax), "=&rm" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#else
- "cpuid"
- : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#endif
- : "a" (eax)
- : "memory"
- );
-}
-
-static INLINE void
-__GET_CPUID2(int eax, // IN
- int ecx, // IN
- CPUIDRegs *regs) // OUT
-{
- __asm__ __volatile__(
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (regs->eax), "=&rm" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#else
- "cpuid"
- : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx), "=d" (regs->edx)
-#endif
- : "a" (eax), "c" (ecx)
- : "memory"
- );
-}
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID(int eax) // IN
-{
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx)
- : "a" (eax)
- : "memory", "%ecx", "%edx"
- );
-#else
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax)
- : "a" (eax)
- : "memory", "%ebx", "%ecx", "%edx"
- );
-#endif
-
- return eax;
-}
-
-static INLINE uint32
-__GET_EBX_FROM_CPUID(int eax) // IN
-{
- uint32 ebx;
-
- __asm__ __volatile__(
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx)
-#else
- "cpuid"
- : "=a" (eax), "=b" (ebx)
-#endif
- : "a" (eax)
- : "memory", "%ecx", "%edx"
- );
-
- return ebx;
-}
-
-static INLINE uint32
-__GET_ECX_FROM_CPUID(int eax) // IN
-{
- uint32 ecx;
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx), "=c" (ecx)
- : "a" (eax)
- : "memory", "%edx"
- );
-#else
-
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax), "=c" (ecx)
- : "a" (eax)
- : "memory", "%ebx", "%edx"
- );
-#endif
-
- return ecx;
-}
-
-static INLINE uint32
-__GET_EDX_FROM_CPUID(int eax) // IN
-{
- uint32 edx;
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx), "=d" (edx)
- : "a" (eax)
- : "memory", "%ecx"
- );
-#else
-
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax), "=d" (edx)
- : "a" (eax)
- : "memory", "%ebx", "%ecx"
- );
-#endif
-
- return edx;
-}
-
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID4(int ecx) // IN
-{
- uint32 eax;
-#if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
- uint32 ebx;
-
- __asm__ __volatile__(
- "movl %%ebx, %1" "\n\t"
- "cpuid" "\n\t"
- "xchgl %%ebx, %1"
- : "=a" (eax), "=&rm" (ebx), "=c" (ecx)
- : "a" (4), "c" (ecx)
- : "memory", "%edx"
- );
-#else
-
- __asm__ __volatile__(
- "cpuid"
- : "=a" (eax), "=c" (ecx)
- : "a" (4), "c" (ecx)
- : "memory", "%ebx", "%edx"
- );
-#endif
-
- return eax;
-}
-
-#elif defined(_MSC_VER) // } {
-static INLINE uint8
-INB(uint16 port)
-{
- return (uint8)_inp(port);
-}
-static INLINE void
-OUTB(uint16 port, uint8 value)
-{
- _outp(port, value);
-}
-static INLINE uint16
-INW(uint16 port)
-{
- return _inpw(port);
-}
-static INLINE void
-OUTW(uint16 port, uint16 value)
-{
- _outpw(port, value);
-}
-static INLINE uint32
-IN32(uint16 port)
-{
- return _inpd(port);
-}
-static INLINE void
-OUT32(uint16 port, uint32 value)
-{
- _outpd(port, value);
-}
-
-#ifndef VM_X86_64
-#ifdef NEAR
-#undef NEAR
-#endif
-
-#define GET_CURRENT_EIP(_eip) do { \
- __asm call NEAR PTR $+5 \
- __asm pop eax \
- __asm mov _eip, eax \
-} while (0)
-#endif
-
-static INLINE void
-__GET_CPUID(int input, CPUIDRegs *regs)
-{
-#ifdef VM_X86_64
- __cpuid((unsigned int *)regs, input);
-#else
- __asm push esi
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm mov esi, regs
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov 0x0[esi], eax
- __asm mov 0x4[esi], ebx
- __asm mov 0x8[esi], ecx
- __asm mov 0xC[esi], edx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
- __asm pop esi
-#endif
-}
-
-#ifdef VM_X86_64
-
-/*
- * No inline assembly in Win64. Implemented in bora/lib/user in
- * cpuidMasm64.asm.
- */
-
-extern void
-__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs);
-
-#else // VM_X86_64
-
-static INLINE void
-__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs)
-{
- __asm push esi
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, inputEax
- __asm mov ecx, inputEcx
- __asm mov esi, regs
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov 0x0[esi], eax
- __asm mov 0x4[esi], ebx
- __asm mov 0x8[esi], ecx
- __asm mov 0xC[esi], edx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
- __asm pop esi
-}
-#endif
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.eax;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, eax
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-static INLINE uint32
-__GET_EBX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.ebx;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, ebx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-static INLINE uint32
-__GET_ECX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.ecx;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, ecx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-static INLINE uint32
-__GET_EDX_FROM_CPUID(int input)
-{
-#ifdef VM_X86_64
- CPUIDRegs regs;
- __cpuid((unsigned int *)®s, input);
- return regs.edx;
-#else
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, input
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, edx
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-#endif
-}
-
-#ifdef VM_X86_64
-
-/*
- * No inline assembly in Win64. Implemented in bora/lib/user in
- * cpuidMasm64.asm.
- */
-
-extern uint32
-__GET_EAX_FROM_CPUID4(int inputEcx);
-
-#else // VM_X86_64
-
-static INLINE uint32
-__GET_EAX_FROM_CPUID4(int inputEcx)
-{
- uint32 output;
-
- //NOT_TESTED();
- __asm push ebx
- __asm push ecx
- __asm push edx
-
- __asm mov eax, 4
- __asm mov ecx, inputEcx
- __asm _emit 0x0f __asm _emit 0xa2
- __asm mov output, eax
-
- __asm pop edx
- __asm pop ecx
- __asm pop ebx
-
- return output;
-}
-
-#endif // VM_X86_64
-
-#else // }
-#error
-#endif
-
-#define CPUID_FOR_SIDE_EFFECTS() ((void)__GET_EAX_FROM_CPUID(0))
-
-static INLINE void
-__GET_CPUID4(int inputEcx, CPUIDRegs *regs)
-{
- __GET_CPUID2(4, inputEcx, regs);
-}
-
-/* The first parameter is used as an rvalue and then as an lvalue. */
-#define GET_CPUID(_ax, _bx, _cx, _dx) { \
- CPUIDRegs regs; \
- __GET_CPUID(_ax, ®s); \
- _ax = regs.eax; \
- _bx = regs.ebx; \
- _cx = regs.ecx; \
- _dx = regs.edx; \
-}
-
-
-/* Sequence recommended by Intel for the Pentium 4. */
-#define INTEL_MICROCODE_VERSION() ( \
- __SET_MSR(MSR_BIOS_SIGN_ID, 0), \
- __GET_EAX_FROM_CPUID(1), \
- __GET_MSR(MSR_BIOS_SIGN_ID))
-
-
-#ifdef _MSC_VER
-static INLINE int
-ffs(uint32 bitVector)
-{
- int idx;
- if (!bitVector) {
- return 0;
- }
-#ifdef VM_X86_64
- _BitScanForward((unsigned long*)&idx, (unsigned long)bitVector);
-#else
- __asm bsf eax, bitVector
- __asm mov idx, eax
-#endif
- return idx+1;
-}
-#endif
-
-#ifdef __GNUC__
-static INLINE void *
-uint16set(void *dst, uint16 val, size_t count)
-{
- int dummy0;
- int dummy1;
-
- __asm__ __volatile__("\t"
- "cld" "\n\t"
- "rep ; stosw" "\n"
- : "=c" (dummy0), "=D" (dummy1)
- : "0" (count), "1" (dst), "a" (val)
- : "memory", "cc"
- );
-
- return dst;
-}
-
-static INLINE void *
-uint32set(void *dst, uint32 val, size_t count)
-{
- int dummy0;
- int dummy1;
-
- __asm__ __volatile__("\t"
- "cld" "\n\t"
- "rep ; stosl" "\n"
- : "=c" (dummy0), "=D" (dummy1)
- : "0" (count), "1" (dst), "a" (val)
- : "memory", "cc"
- );
-
- return dst;
-}
-
-#elif defined(_MSC_VER)
-
-static INLINE void *
-uint16set(void *dst, uint16 val, size_t count)
-{
-#ifdef VM_X86_64
- __stosw((uint16*)dst, val, count);
-#else
- __asm { pushf;
- mov ax, val;
- mov ecx, count;
- mov edi, dst;
- cld;
- rep stosw;
- popf;
- }
-#endif
- return dst;
-}
-
-static INLINE void *
-uint32set(void *dst, uint32 val, size_t count)
-{
-#ifdef VM_X86_64
- __stosd((unsigned long*)dst, (unsigned long)val, count);
-#else
- __asm { pushf;
- mov eax, val;
- mov ecx, count;
- mov edi, dst;
- cld;
- rep stosd;
- popf;
- }
-#endif
- return dst;
-}
-
-#else
-#error "No compiler defined for uint*set"
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Bswap32 --
- *
- * Swap the 4 bytes of "v" as follows: 3210 -> 0123.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint32
-Bswap32(uint32 v) // IN
-{
-#ifdef __GNUC__ // {
- /* Checked against the Intel manual and GCC. --hpreg */
- __asm__(
- "bswap %0"
- : "=r" (v)
- : "0" (v)
- );
- return v;
-#else // } {
- return (v >> 24)
- | ((v >> 8) & 0xFF00)
- | ((v & 0xFF00) << 8)
- | (v << 24) ;
-#endif // }
-}
-#define Bswap Bswap32
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Bswap64 --
- *
- * Swap the 8 bytes of "v" as follows: 76543210 -> 01234567.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-Bswap64(uint64 v) // IN
-{
- return ((uint64)Bswap((uint32)v) << 32) | Bswap((uint32)(v >> 32));
-}
-
-
-#ifdef __GNUC__ // {
-/*
- * COMPILER_MEM_BARRIER prevents the compiler from re-ordering memory
- * references accross the barrier. NOTE: It does not generate any
- * instruction, so the CPU is free to do whatever it wants to...
- */
-#define COMPILER_MEM_BARRIER() __asm__ __volatile__ ("": : :"memory")
-#elif defined(_MSC_VER) // } {
-#define COMPILER_MEM_BARRIER() _ReadWriteBarrier()
-#endif // }
-
-
-/*
- * PAUSE is a P4 instruction that improves spinlock power+performance;
- * on non-P4 IA32 systems, the encoding is interpreted as a REPZ-NOP.
- * Use volatile to avoid NOP removal.
- */
-static INLINE void
-PAUSE(void)
-#ifdef __GNUC__
-{
- __asm__ __volatile__( "pause" :);
-}
-#elif defined(_MSC_VER)
-#ifdef VM_X86_64
-{
- _mm_pause();
-}
-#else /* VM_X86_64 */
-#pragma warning( disable : 4035)
-{
- __asm _emit 0xf3 __asm _emit 0x90
-}
-#pragma warning (default: 4035)
-#endif /* VM_X86_64 */
-#else /* __GNUC__ */
-#error No compiler defined for PAUSE
-#endif
-
-
-/*
- * Checked against the Intel manual and GCC --hpreg
- *
- * volatile because the tsc always changes without the compiler knowing it.
- */
-static INLINE uint64
-RDTSC(void)
-#ifdef __GNUC__
-{
-#ifdef VM_X86_64
- uint64 tscLow;
- uint64 tscHigh;
-
- __asm__ __volatile__(
- "rdtsc"
- : "=a" (tscLow), "=d" (tscHigh)
- );
-
- return tscHigh << 32 | tscLow;
-#else
- uint64 tim;
-
- __asm__ __volatile__(
- "rdtsc"
- : "=A" (tim)
- );
-
- return tim;
-#endif
-}
-#elif defined(_MSC_VER)
-#ifdef VM_X86_64
-{
- return __rdtsc();
-}
-#else
-#pragma warning( disable : 4035)
-{
- __asm _emit 0x0f __asm _emit 0x31
-}
-#pragma warning (default: 4035)
-#endif /* VM_X86_64 */
-#else /* __GNUC__ */
-#error No compiler defined for RDTSC
-#endif /* __GNUC__ */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DEBUGBREAK --
- *
- * Does an int3 for MSVC / GCC. This is a macro to make sure int3 is
- * always inlined.
- *
- *-----------------------------------------------------------------------------
- */
-
-#ifdef _MSC_VER
-#define DEBUGBREAK() __debugbreak()
-#else
-#define DEBUGBREAK() __asm__ (" int $3 ")
-#endif
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_asm_x86.h
- *
- * Basic IA32 asm macros
- */
-
-#ifndef _VM_BASIC_ASM_X86_H_
-#define _VM_BASIC_ASM_X86_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-#ifdef VM_X86_64
-/*
- * The gcc inline asm uses the "A" constraint which differs in 32 & 64
- * bit mode. 32 bit means eax and edx, 64 means rax or rdx.
- */
-#error "x86-64 not supported"
-#endif
-
-
-
-
-/*
- * from linux: usr/include/asm/io.h
- */
-#ifdef __GNUC__
-#ifndef __SLOW_DOWN_IO
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
-#else
-#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
-#endif
-#endif
-#elif _MSC_VER
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO __asm jmp SHORT $+2 __asm jmp SHORT $+2
-#else
-#define __SLOW_DOWN_IO __asm out 80h,al
-#endif
-#else
-#error
-#endif
-
-#ifdef REALLY_SLOW_IO
-#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
-#else
-#define SLOW_DOWN_IO __SLOW_DOWN_IO
-#endif
-
-/*
- * FXSAVE/FXRSTOR
- * save/restore SIMD/MMX fpu state
- *
- * The pointer passed in must be 16-byte aligned.
- *
- * Intel and AMD processors behave differently w.r.t. fxsave/fxrstor. Intel
- * processors unconditionally save the exception pointer state (instruction
- * ptr., data ptr., and error instruction opcode). FXSAVE_ES1 and FXRSTOR_ES1
- * work correctly for Intel processors.
- *
- * AMD processors only save the exception pointer state if ES=1. This leads to a
- * security hole whereby one process/VM can inspect the state of another process
- * VM. The AMD recommended workaround involves clobbering the exception pointer
- * state unconditionally, and this is implemented in FXRSTOR_AMD_ES0. Note that
- * FXSAVE_ES1 will only save the exception pointer state for AMD processors if
- * ES=1.
- *
- * The workaround (FXRSTOR_AMD_ES0) only costs 1 cycle more than just doing an
- * fxrstor, on both AMD Opteron and Intel Core CPUs.
- */
-#if defined(__GNUC__)
-static INLINE void
-FXSAVE_ES1(uint8 *save)
-{
- __asm__ __volatile__ ("fxsave %0\n" : "=m" (*save) : : "memory");
-}
-
-static INLINE void
-FXRSTOR_ES1(const uint8 *load)
-{
- __asm__ __volatile__ ("fxrstor %0\n" : : "m" (*load) : "memory");
-}
-
-static INLINE void
-FXRSTOR_AMD_ES0(const uint8 *load)
-{
- uint64 dummy = 0;
-
- __asm__ __volatile__
- ("fnstsw %%ax \n" // Grab x87 ES bit
- "bt $7,%%ax \n" // Test ES bit
- "jnc 1f \n" // Jump if ES=0
- "fnclex \n" // ES=1. Clear it so fild doesn't trap
- "1: \n"
- "ffree %%st(7) \n" // Clear tag bit - avoid poss. stack overflow
- "fildl %0 \n" // Dummy Load from "safe address" changes all
- // x87 exception pointers.
- "fxrstor %1 \n"
- :
- : "m" (dummy), "m" (*load)
- : "ax", "memory");
-}
-#endif /* __GNUC__ */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643232 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 32-bit wide
- *
- * Use this function if you are certain that:
- * o Either the quotient will fit in 32 bits,
- * o Or your code is ready to handle a #DE exception indicating overflow.
- * If that is not the case, then use Div643264(). --hpreg
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE void
-Div643232(uint64 dividend, // IN
- uint32 divisor, // IN
- uint32 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- /* Checked against the Intel manual and GCC --hpreg */
- __asm__(
- "divl %4"
- : "=a" (*quotient),
- "=d" (*remainder)
- : "0" ((uint32)dividend),
- "1" ((uint32)(dividend >> 32)),
- "rm" (divisor)
- : "cc"
- );
-}
-
-#elif _MSC_VER
-
-static INLINE void
-Div643232(uint64 dividend, // IN
- uint32 divisor, // IN
- uint32 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- /* Written and tested by mann, checked by dbudko and hpreg */
- __asm {
- mov eax, DWORD PTR [dividend]
- mov edx, DWORD PTR [dividend+4]
- div DWORD PTR [divisor]
- mov edi, DWORD PTR [quotient]
- mov [edi], eax
- mov edi, DWORD PTR [remainder]
- mov [edi], edx
- }
-}
-
-#else
-#error No compiler defined for Div643232
-#endif
-
-
-#if defined(__GNUC__)
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643264 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 64-bit wide --hpreg
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Div643264(uint64 dividend, // IN
- uint32 divisor, // IN
- uint64 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- uint32 hQuotient;
- uint32 lQuotient;
-
- /* Checked against the Intel manual and GCC --hpreg */
- __asm__(
- "divl %5" "\n\t"
- "movl %%eax, %0" "\n\t"
- "movl %4, %%eax" "\n\t"
- "divl %5"
- : "=&rm" (hQuotient),
- "=a" (lQuotient),
- "=d" (*remainder)
- : "1" ((uint32)(dividend >> 32)),
- "g" ((uint32)dividend),
- "rm" (divisor),
- "2" (0)
- : "cc"
- );
- *quotient = (uint64)hQuotient << 32 | lQuotient;
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Mul64x3264 --
- *
- * Unsigned integer by fixed point multiplication:
- * Unsigned 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Unsigned 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x32 bits to yield a full 96-bit product.
- * Shift right by shift.
- * Return the low-order 64 bits of the result.
- *
- * Result:
- * Product
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
-{
- uint64 result;
- uint32 tmp1, tmp2;
- // ASSERT(shift >= 0 && shift < 64);
-
- /*
- * Written and tested by mann, improved with suggestions by hpreg.
- *
- * The main improvement over the previous version is that the test
- * of shift against 32 is moved out of the asm and into C code.
- * This lets the compiler delete the test and one of the
- * alternative code sequences in the case where shift is a
- * constant. It also lets us use the best code sequence in each
- * alternative, rather than a compromise. The downside is that in
- * the non-constant case, this version takes slightly more code
- * space.
- *
- * Note on the constraints: We don't really want multiplicand to
- * start in %edx:%eax as the =A constraint dictates; in fact, we'd
- * prefer any *other* two registers. But gcc doesn't have
- * constraint syntax for any other register pair, and trying to
- * constrain ((uint32) multiplicand) to one place and (multiplicand
- * >> 32) to another generates *really* bad code -- gcc is just not
- * smart enough, at least in the version we are currently using.
- */
- if (shift < 32) {
- __asm__("mov %%eax, %2 \n\t" // Save lo(multiplicand) in tmp2
- "mov %%edx, %%eax \n\t" // Get hi(multiplicand)
- "mull %4 \n\t" // p2 = hi(multiplicand) * multiplier
- "xchg %%eax, %2 \n\t" // Save lo(p2) in tmp2, get lo(multiplicand)
- "mov %%edx, %1 \n\t" // Save hi(p2) in tmp1
- "mull %4 \n\t" // p1 = lo(multiplicand) * multiplier
- "addl %2, %%edx \n\t" // hi(p1) += lo(p2)
- "adcl $0, %1 \n\t" // hi(p2) += carry from previous step
- "shrdl %%edx, %%eax \n\t" // result = hi(p2):hi(p1):lo(p1) >> shift
- "shrdl %1, %%edx"
- : "=A" (result),
- "=&r" (tmp1), // use in shrdl requires it to be a register
- "=&r" (tmp2) // could be "=&rm" but "m" is slower
- : "0" (multiplicand),
- "rm" (multiplier),
- "c" (shift)
- : "cc"
- );
- } else {
- __asm__("mov %%edx, %2 \n\t" // Save hi(multiplicand) in tmp2
- "mull %4 \n\t" // p1 = lo(multiplicand) * multiplier
- "mov %%edx, %1 \n\t" // Save hi(p1) in tmp1
- "mov %2, %%eax \n\t" // Discard lo(p1), get hi(multiplicand)
- "mull %4 \n\t" // p2 = hi(multiplicand) * multiplier
- "addl %1, %%eax \n\t" // lo(p2) += hi(p1)
- "adcl $0, %%edx \n\t" // hi(p2) += carry from previous step
- "shrdl %%edx, %%eax \n\t" // result = p2 >> (shift & 31)
- "shrl %%cl, %%edx"
- : "=A" (result),
- "=&r" (tmp1), // could be "=&rm" but "m" is slower
- "=&r" (tmp2) // could be "=&rm" but "m" is slower
- : "0" (multiplicand),
- "rm" (multiplier),
- "c" (shift)
- : "cc"
- );
- }
- return result;
-}
-
-#elif _MSC_VER
-#pragma warning(disable: 4035)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
-{
- // ASSERT(shift >= 0 && shift < 64);
-
- /* Written and tested by mann, checked by dbudko and hpreg */
- __asm {
- mov eax, DWORD PTR [multiplicand+4] // Get hi(multiplicand)
- mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier
- mov ecx, eax // Save lo(p2)
- mov ebx, edx // Save hi(p2)
- mov eax, DWORD PTR [multiplicand] // Get lo(multiplicand)
- mul DWORD PTR [multiplier+0] // p1 = lo(multiplicand) * multiplier
- add edx, ecx // hi(p1) += lo(p2)
- adc ebx, 0 // hi(p2) += carry from previous step
- mov ecx, DWORD PTR [shift] // Get shift
- cmp ecx, 32 // shift < 32?
- jl SHORT l2 // Go if so
- mov eax, edx // result = hi(p2):hi(p1) >> (shift & 31)
- mov edx, ebx
- shrd eax, edx, cl
- shr edx, cl
- jmp SHORT l3
- l2:
- shrd eax, edx, cl // result = hi(p2):hi(p1):lo(p1) >> shift
- shrd edx, ebx, cl
- l3:
- }
- // return with result in edx:eax
-}
-
-#pragma warning(default: 4035)
-#else
-#error No compiler defined for Mul64x3264
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Muls64x32s64 --
- *
- * Signed integer by fixed point multiplication:
- * Signed 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Signed 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x32 bits to yield a full 96-bit product.
- * Shift right by the location of the binary point.
- * Return the low-order 64 bits of the result.
- *
- * Result:
- * Product
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- int64 result;
- uint32 tmp1, tmp2;
- // ASSERT(shift >= 0 && shift < 64);
-
- /* Written and tested by mann, checked by dbudko and hpreg */
- /* XXX hpreg suggested some improvements that we haven't converged on yet */
- __asm__("mov %%eax, %2\n\t" // Save lo(multiplicand)
- "mov %%edx, %%eax\n\t" // Get hi(multiplicand)
- "test %%eax, %%eax\n\t" // Check sign of multiplicand
- "jl 0f\n\t" // Go if negative
- "mull %4\n\t" // p2 = hi(multiplicand) * multiplier
- "jmp 1f\n"
- "0:\n\t"
- "mull %4\n\t" // p2 = hi(multiplicand) * multiplier
- "sub %4, %%edx\n" // hi(p2) += -1 * multiplier
- "1:\n\t"
- "xchg %%eax, %2\n\t" // Save lo(p2), get lo(multiplicand)
- "mov %%edx, %1\n\t" // Save hi(p2)
- "mull %4\n\t" // p1 = lo(multiplicand) * multiplier
- "addl %2, %%edx\n\t" // hi(p1) += lo(p2)
- "adcl $0, %1\n\t" // hi(p2) += carry from previous step
- "cmpl $32, %%ecx\n\t" // shift < 32?
- "jl 2f\n\t" // Go if so
- "mov %%edx, %%eax\n\t" // result = hi(p2):hi(p1) >> (shift & 31)
- "mov %1, %%edx\n\t"
- "shrdl %%edx, %%eax\n\t"
- "sarl %%cl, %%edx\n\t"
- "jmp 3f\n"
- "2:\n\t"
- "shrdl %%edx, %%eax\n\t" // result = hi(p2):hi(p1):lo(p1) >> shift
- "shrdl %1, %%edx\n"
- "3:\n\t"
- : "=A" (result), "=&r" (tmp1), "=&r" (tmp2)
- : "0" (multiplicand), "rm" (multiplier), "c" (shift)
- : "cc");
- return result;
-}
-
-#elif _MSC_VER
-#pragma warning(disable: 4035)
-
-static INLINE int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- //ASSERT(shift >= 0 && shift < 64);
-
- /* Written and tested by mann, checked by dbudko and hpreg */
- __asm {
- mov eax, DWORD PTR [multiplicand+4] // Get hi(multiplicand)
- test eax, eax // Check sign of multiplicand
- jl SHORT l0 // Go if negative
- mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier
- jmp SHORT l1
- l0:
- mul DWORD PTR [multiplier] // p2 = hi(multiplicand) * multiplier
- sub edx, DWORD PTR [multiplier] // hi(p2) += -1 * multiplier
- l1:
- mov ecx, eax // Save lo(p2)
- mov ebx, edx // Save hi(p2)
- mov eax, DWORD PTR [multiplicand] // Get lo(multiplicand)
- mul DWORD PTR [multiplier] // p1 = lo(multiplicand) * multiplier
- add edx, ecx // hi(p1) += lo(p2)
- adc ebx, 0 // hi(p2) += carry from previous step
- mov ecx, DWORD PTR [shift] // Get shift
- cmp ecx, 32 // shift < 32?
- jl SHORT l2 // Go if so
- mov eax, edx // result = hi(p2):hi(p1) >> (shift & 31)
- mov edx, ebx
- shrd eax, edx, cl
- sar edx, cl
- jmp SHORT l3
- l2:
- shrd eax, edx, cl // result = hi(p2):hi(p1):lo(p1) << shift
- shrd edx, ebx, cl
- l3:
- }
- // return with result in edx:eax
-}
-
-#pragma warning(default: 4035)
-#else
-#error No compiler defined for Muls64x32s64
-#endif
-
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_asm_x86_64.h
- *
- * Basic x86_64 asm macros.
- */
-
-#ifndef _VM_BASIC_ASM_X86_64_H_
-#define _VM_BASIC_ASM_X86_64_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMNIXMOD
-#include "includeCheck.h"
-
-#ifndef VM_X86_64
-#error "This file is x86-64 only!"
-#endif
-
-#ifdef _MSC_VER
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-uint64 _umul128(uint64 multiplier, uint64 multiplicand,
- uint64 *highProduct);
-int64 _mul128(int64 multiplier, int64 multiplicand,
- int64 *highProduct);
-uint64 __shiftright128(uint64 lowPart, uint64 highPart, uint8 shift);
-#ifdef __cplusplus
-}
-#endif
-
-#pragma intrinsic(_umul128, _mul128, __shiftright128)
-
-#endif // _MSC_VER
-
-/*
- * FXSAVE/FXRSTOR
- * save/restore SIMD/MMX fpu state
- *
- * The pointer passed in must be 16-byte aligned.
- *
- * Intel and AMD processors behave differently w.r.t. fxsave/fxrstor. Intel
- * processors unconditionally save the exception pointer state (instruction
- * ptr., data ptr., and error instruction opcode). FXSAVE_ES1 and FXRSTOR_ES1
- * work correctly for Intel processors.
- *
- * AMD processors only save the exception pointer state if ES=1. This leads to a
- * security hole whereby one process/VM can inspect the state of another process
- * VM. The AMD recommended workaround involves clobbering the exception pointer
- * state unconditionally, and this is implemented in FXRSTOR_AMD_ES0. Note that
- * FXSAVE_ES1 will only save the exception pointer state for AMD processors if
- * ES=1.
- *
- * The workaround (FXRSTOR_AMD_ES0) only costs 1 cycle more than just doing an
- * fxrstor, on both AMD Opteron and Intel Core CPUs.
- */
-#if defined(__GNUC__)
-
-static INLINE void
-FXSAVE_ES1(uint8 *save)
-{
- __asm__ __volatile__ ("fxsaveq %0 \n" : "=m" (*save) : : "memory");
-}
-
-static INLINE void
-FXSAVE_COMPAT_ES1(uint8 *save)
-{
- __asm__ __volatile__ ("fxsave %0 \n" : "=m" (*save) : : "memory");
-}
-
-static INLINE void
-FXRSTOR_ES1(const uint8 *load)
-{
- __asm__ __volatile__ ("fxrstorq %0 \n" : : "m" (*load) : "memory");
-}
-
-static INLINE void
-FXRSTOR_COMPAT_ES1(const uint8 *load)
-{
- __asm__ __volatile__ ("fxrstor %0 \n" : : "m" (*load) : "memory");
-}
-
-static INLINE void
-FXRSTOR_AMD_ES0(const uint8 *load)
-{
- uint64 dummy = 0;
-
- __asm__ __volatile__
- ("fnstsw %%ax \n" // Grab x87 ES bit
- "bt $7,%%ax \n" // Test ES bit
- "jnc 1f \n" // Jump if ES=0
- "fnclex \n" // ES=1. Clear it so fild doesn't trap
- "1: \n"
- "ffree %%st(7) \n" // Clear tag bit - avoid poss. stack overflow
- "fildl %0 \n" // Dummy Load from "safe address" changes all
- // x87 exception pointers.
- "fxrstorq %1 \n"
- :
- : "m" (dummy), "m" (*load)
- : "ax", "memory");
-}
-
-#endif /* __GNUC__ */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Mul64x3264 --
- *
- * Unsigned integer by fixed point multiplication:
- * result = multiplicand * multiplier >> shift
- *
- * Unsigned 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Unsigned 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x64 bits to yield a full 128-bit product.
- * Shift result in RDX:RAX right by "shift".
- * Return the low-order 64 bits of the above.
- *
- * Result:
- * Product
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand,
- uint32 multiplier,
- uint32 shift)
-{
- uint64 result, dummy;
- const uint64 multiplier64 = multiplier;
-
- __asm__("mulq %3 \n\t"
- "shrdq %1, %0 \n\t"
- : "=a" (result),
- "=d" (dummy)
- : "0" (multiplier64),
- "rm" (multiplicand),
- "c" (shift)
- : "cc");
- return result;
-}
-
-#elif defined(_MSC_VER)
-
-static INLINE uint64
-Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
-{
- uint64 tmplo, tmphi;
- tmplo = _umul128(multiplicand, multiplier, &tmphi);
- return __shiftright128(tmplo, tmphi, (uint8) shift);
-}
-
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Muls64x32s64 --
- *
- * Signed integer by fixed point multiplication:
- * result = multiplicand * multiplier >> shift
- *
- * Signed 64-bit integer multiplicand.
- * Unsigned 32-bit fixed point multiplier, represented as
- * multiplier >> shift, where shift < 64.
- * Signed 64-bit integer product.
- *
- * Implementation:
- * Multiply 64x64 bits to yield a full 128-bit product.
- * Shift result in RDX:RAX right by "shift".
- * Return the low-order 64 bits of the above.
- *
- * Note: using an unsigned shift instruction is correct because
- * shift < 64 and we return only the low 64 bits of the shifted
- * result.
- *
- * Result:
- * Product
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static inline int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- int64 result, dummy;
- const int64 multiplier64 = multiplier;
-
- __asm__("imulq %3 \n\t"
- "shrdq %1, %0 \n\t"
- : "=a" (result),
- "=d" (dummy)
- : "0" (multiplier64),
- "rm" (multiplicand),
- "c" (shift)
- : "cc");
- return result;
-}
-
-#elif defined(_MSC_VER)
-
-static INLINE int64
-Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
-{
- int64 tmplo, tmphi;
- tmplo = _mul128(multiplicand, multiplier, &tmphi);
- return __shiftright128(tmplo, tmphi, (uint8) shift);
-}
-
-#endif
-
-
-#if defined(__GNUC__)
-
-static INLINE void *
-uint64set(void *dst, uint64 val, uint64 count)
-{
- int dummy0;
- int dummy1;
- __asm__ __volatile__("\t"
- "cld" "\n\t"
- "rep ; stosq" "\n"
- : "=c" (dummy0), "=D" (dummy1)
- : "0" (count), "1" (dst), "a" (val)
- : "memory", "cc");
- return dst;
-}
-
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643232 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 32-bit wide
- *
- * Use this function if you are certain that the quotient will fit in 32 bits,
- * If that is not the case, a #DE exception was generated in 32-bit version,
- * but not in this 64-bit version. So please be careful.
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__) || defined(_MSC_VER)
-
-static INLINE void
-Div643232(uint64 dividend, // IN
- uint32 divisor, // IN
- uint32 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- *quotient = (uint32)(dividend / divisor);
- *remainder = (uint32)(dividend % divisor);
-}
-
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Div643264 --
- *
- * Unsigned integer division:
- * The dividend is 64-bit wide
- * The divisor is 32-bit wide
- * The quotient is 64-bit wide
- *
- * Results:
- * Quotient and remainder
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(__GNUC__)
-
-static INLINE void
-Div643264(uint64 dividend, // IN
- uint32 divisor, // IN
- uint64 *quotient, // OUT
- uint32 *remainder) // OUT
-{
- *quotient = dividend / divisor;
- *remainder = dividend % divisor;
-}
-
-#endif
-
-#endif // _VM_BASIC_ASM_X86_64_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vm_basic_defs.h --
- *
- * Standard macros for VMware source code.
- */
-
-#ifndef _VM_BASIC_DEFS_H_
-#define _VM_BASIC_DEFS_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-#include "vm_basic_types.h" // For INLINE.
-
-/* Checks for FreeBSD, filtering out VMKERNEL. */
-#define __IS_FREEBSD__ (!defined(VMKERNEL) && defined(__FreeBSD__))
-#define __IS_FREEBSD_VER__(ver) (__IS_FREEBSD__ && __FreeBSD_version >= (ver))
-
-#if defined _WIN32 && defined USERLEVEL
- #include <stddef.h> /*
- * We re-define offsetof macro from stddef, make
- * sure that its already defined before we do it
- */
- #include <windows.h> // for Sleep() and LOWORD() etc.
-#endif
-
-
-/*
- * Simple macros
- */
-
-#if (defined __APPLE__ || defined __FreeBSD__) && \
- (!defined KERNEL && !defined _KERNEL && !defined VMKERNEL && !defined __KERNEL__)
-# include <stddef.h>
-#else
-// XXX the _WIN32 one matches that of VC++, to prevent redefinition warning
-// XXX the other one matches that of gcc3.3.3/glibc2.2.4 to prevent redefinition warnings
-#ifndef offsetof
-#ifdef _WIN32
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-#endif
-#endif // __APPLE__
-
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(a) (sizeof (a) / sizeof *(a))
-#endif
-
-#ifndef MIN
-#define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
-#endif
-
-/* The Solaris 9 cross-compiler complains about these not being used */
-#ifndef sun
-static INLINE int
-Min(int a, int b)
-{
- return a < b ? a : b;
-}
-#endif
-
-#ifndef MAX
-#define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
-#endif
-
-#ifndef sun
-static INLINE int
-Max(int a, int b)
-{
- return a > b ? a : b;
-}
-#endif
-
-#define ROUNDUP(x,y) (((x) + (y) - 1) / (y) * (y))
-#define ROUNDDOWN(x,y) ((x) / (y) * (y))
-#define ROUNDUPBITS(x, bits) (((uintptr_t) (x) + MASK(bits)) & ~MASK(bits))
-#define ROUNDDOWNBITS(x, bits) ((uintptr_t) (x) & ~MASK(bits))
-#define CEILING(x, y) (((x) + (y) - 1) / (y))
-#if defined __APPLE__
-#include <machine/param.h>
-#undef MASK
-#endif
-#define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */
-#define DWORD_ALIGN(x) ((((x)+3) >> 2) << 2)
-#define QWORD_ALIGN(x) ((((x)+4) >> 3) << 3)
-
-#define IMPLIES(a,b) (!(a) || (b))
-
-/*
- * Not everybody (e.g., the monitor) has NULL
- */
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *)0)
-#endif
-#endif
-
-
-/*
- * Token concatenation
- *
- * The C preprocessor doesn't prescan arguments when they are
- * concatenated or stringified. So we need extra levels of
- * indirection to convince the preprocessor to expand its
- * arguments.
- */
-
-#define CONC(x, y) x##y
-#define XCONC(x, y) CONC(x, y)
-#define XXCONC(x, y) XCONC(x, y)
-#define MAKESTR(x) #x
-#define XSTR(x) MAKESTR(x)
-
-
-/*
- * Page operations
- *
- * It has been suggested that these definitions belong elsewhere
- * (like x86types.h). However, I deem them common enough
- * (since even regular user-level programs may want to do
- * page-based memory manipulation) to be here.
- * -- edward
- */
-
-#ifndef PAGE_SHIFT // {
-#if defined VM_I386
- #define PAGE_SHIFT 12
-#elif defined __APPLE__
- #define PAGE_SHIFT 12
-#else
- #error
-#endif
-#endif // }
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE (1<<PAGE_SHIFT)
-#endif
-
-#ifndef PAGE_MASK
-#define PAGE_MASK (PAGE_SIZE - 1)
-#endif
-
-#ifndef PAGE_OFFSET
-#define PAGE_OFFSET(_addr) ((uintptr_t)(_addr)&(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGE_BASE
-#define VM_PAGE_BASE(_addr) ((_addr)&~(PAGE_SIZE-1))
-#endif
-
-#ifndef VM_PAGES_SPANNED
-#define VM_PAGES_SPANNED(_addr, _size) \
- ((((_addr) & (PAGE_SIZE - 1)) + (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
-#endif
-
-#ifndef BYTES_2_PAGES
-#define BYTES_2_PAGES(_nbytes) ((_nbytes) >> PAGE_SHIFT)
-#endif
-
-#ifndef PAGES_2_BYTES
-#define PAGES_2_BYTES(_npages) (((uint64)(_npages)) << PAGE_SHIFT)
-#endif
-
-#ifndef MBYTES_2_PAGES
-#define MBYTES_2_PAGES(_nbytes) ((_nbytes) << (20 - PAGE_SHIFT))
-#endif
-
-#ifndef PAGES_2_MBYTES
-#define PAGES_2_MBYTES(_npages) ((_npages) >> (20 - PAGE_SHIFT))
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SHIFT
-#define VM_PAE_LARGE_PAGE_SHIFT 21
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_SIZE
-#define VM_PAE_LARGE_PAGE_SIZE (1 << VM_PAE_LARGE_PAGE_SHIFT)
-#endif
-
-#ifndef VM_PAE_LARGE_PAGE_MASK
-#define VM_PAE_LARGE_PAGE_MASK (VM_PAE_LARGE_PAGE_SIZE - 1)
-#endif
-
-#ifndef VM_PAE_LARGE_2_SMALL_PAGES
-#define VM_PAE_LARGE_2_SMALL_PAGES (BYTES_2_PAGES(VM_PAE_LARGE_PAGE_SIZE))
-#endif
-
-/*
- * Word operations
- */
-
-#ifndef LOWORD
-#define LOWORD(_dw) ((_dw) & 0xffff)
-#endif
-#ifndef HIWORD
-#define HIWORD(_dw) (((_dw) >> 16) & 0xffff)
-#endif
-
-#ifndef LOBYTE
-#define LOBYTE(_w) ((_w) & 0xff)
-#endif
-#ifndef HIBYTE
-#define HIBYTE(_w) (((_w) >> 8) & 0xff)
-#endif
-
-#define HIDWORD(_qw) ((uint32)((_qw) >> 32))
-#define LODWORD(_qw) ((uint32)(_qw))
-#define QWORD(_hi, _lo) ((((uint64)(_hi)) << 32) | ((uint32)(_lo)))
-
-
-/*
- * Deposit a field _src at _pos bits from the right,
- * with a length of _len, into the integer _target.
- */
-
-#define DEPOSIT_BITS(_src,_pos,_len,_target) { \
- unsigned mask = ((1 << _len) - 1); \
- unsigned shiftedmask = ((1 << _len) - 1) << _pos; \
- _target = (_target & ~shiftedmask) | ((_src & mask) << _pos); \
-}
-
-
-/*
- * Get return address.
- */
-
-#ifdef _MSC_VER
-#ifdef __cplusplus
-extern "C"
-#endif
-void *_ReturnAddress(void);
-#pragma intrinsic(_ReturnAddress)
-#define GetReturnAddress() _ReturnAddress()
-#elif __GNUC__
-#define GetReturnAddress() __builtin_return_address(0)
-#endif
-
-
-#ifdef __GNUC__
-#ifndef sun
-
-/*
- * Get the frame pointer. We use this assembly hack instead of
- * __builtin_frame_address() due to a bug introduced in gcc 4.1.1
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetFrameAddr(void)
-{
- uintptr_t bp;
-#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0))
- bp = (uintptr_t)__builtin_frame_address(0);
-#elif (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 3)
-# if defined(VMM64) || defined(VM_X86_64)
- __asm__ __volatile__("movq %%rbp, %0\n" : "=g" (bp));
-# else
- __asm__ __volatile__("movl %%ebp, %0\n" : "=g" (bp));
-# endif
-#else
- __asm__ __volatile__(
-#ifdef __linux__
- ".print \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
- ".abort"
-#else /* MacOS */
- ".abort \"This newer version of GCC may or may not have the "
- "__builtin_frame_address bug. Need to update this. "
- "See bug 147638.\"\n"
-#endif
- : "=g" (bp)
- );
-#endif
- return bp;
-}
-
-
-/*
- * Returns the frame pointer of the calling function.
- * Equivalent to __builtin_frame_address(1).
- */
-static INLINE_SINGLE_CALLER uintptr_t
-GetCallerFrameAddr(void)
-{
- return *(uintptr_t*)GetFrameAddr();
-}
-
-#endif // sun
-#endif // __GNUC__
-
-/*
- * Data prefetch was added in gcc 3.1.1
- * http://www.gnu.org/software/gcc/gcc-3.1/changes.html
- */
-#ifdef __GNUC__
-# if ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 1) || \
- (__GNUC__ == 3 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 1))
-# define PREFETCH_R(var) __builtin_prefetch((var), 0 /* read */, \
- 3 /* high temporal locality */)
-# define PREFETCH_W(var) __builtin_prefetch((var), 1 /* write */, \
- 3 /* high temporal locality */)
-# else
-# define PREFETCH_R(var) ((void)(var))
-# define PREFETCH_W(var) ((void)(var))
-# endif
-#endif /* __GNUC__ */
-
-
-#ifdef USERLEVEL // {
-
-/*
- * Note this might be a problem on NT b/c while sched_yield guarantees it
- * moves you to the end of your priority list, Sleep(0) offers no such
- * guarantee. Bummer. --Jeremy.
- */
-
-#if defined(N_PLAT_NLM)
-/* We do not have YIELD() as we do not need it yet... */
-#elif defined(_WIN32)
-# define YIELD() Sleep(0)
-#else
-# include <sched.h> // For sched_yield. Don't ask. --Jeremy.
-# define YIELD() sched_yield()
-#endif
-
-
-/*
- * Standardize some Posix names on Windows.
- */
-
-#ifdef _WIN32 // {
-
-#define snprintf _snprintf
-#define strtok_r strtok_s
-
-#if (_MSC_VER < 1500)
-#define vsnprintf _vsnprintf
-#endif
-
-typedef int uid_t;
-typedef int gid_t;
-
-static INLINE void
-sleep(unsigned int sec)
-{
- Sleep(sec * 1000);
-}
-
-static INLINE void
-usleep(unsigned long usec)
-{
- Sleep(CEILING(usec, 1000));
-}
-
-typedef int pid_t;
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-#define R_OK 4
-
-#endif // }
-
-/*
- * Macro for username comparison.
- */
-
-#ifdef _WIN32 // {
-#define USERCMP(x,y) Str_Strcasecmp(x,y)
-#else
-#define USERCMP(x,y) strcmp(x,y)
-#endif // }
-
-
-#endif // }
-
-#ifndef va_copy
-
-#ifdef _WIN32
-
-/*
- * Windows needs va_copy. This works for both 32 and 64-bit Windows
- * based on inspection of how varags.h from the Visual C CRTL is
- * implemented. (Future versions of the RTL may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__APPLE__) && defined(KERNEL)
-
-/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
- */
-
-#define va_copy(dest, src) ((dest) = (src))
-
-#elif defined(__GNUC__) && (__GNUC__ < 3)
-
-/*
- * Old versions of gcc recognize __va_copy, but not va_copy.
- */
-
-#define va_copy(dest, src) __va_copy(dest, src)
-
-#endif // _WIN32
-
-#endif // va_copy
-
-/*
- * This one is outside USERLEVEL because it's used by
- * files compiled into the Windows hgfs driver or the display
- * driver.
- */
-
-#ifdef _WIN32
-#define PATH_MAX 256
-#ifndef strcasecmp
-#define strcasecmp(_s1,_s2) _stricmp((_s1),(_s2))
-#endif
-#ifndef strncasecmp
-#define strncasecmp(_s1,_s2,_n) _strnicmp((_s1),(_s2),(_n))
-#endif
-#endif
-
-/*
- * Convenience macro for COMMUNITY_SOURCE
- */
-#undef EXCLUDE_COMMUNITY_SOURCE
-#ifdef COMMUNITY_SOURCE
- #define EXCLUDE_COMMUNITY_SOURCE(x)
-#else
- #define EXCLUDE_COMMUNITY_SOURCE(x) x
-#endif
-
-#undef COMMUNITY_SOURCE_INTEL_SECRET
-#if !defined(COMMUNITY_SOURCE) || defined(INTEL_SOURCE)
-/*
- * It's ok to include INTEL_SECRET source code for non-commsrc,
- * or for drops directed at Intel.
- */
- #define COMMUNITY_SOURCE_INTEL_SECRET
-#endif
-
-/*
- * Convenience macros and definitions. Can often be used instead of #ifdef.
- */
-
-#undef DEBUG_ONLY
-#undef SL_DEBUG_ONLY
-#undef VMX86_SL_DEBUG
-#ifdef VMX86_DEBUG
-#define vmx86_debug 1
-#define DEBUG_ONLY(x) x
-/*
- * Be very, very, very careful with SL_DEBUG. Pls ask ganesh or min before
- * using it.
- */
-#define VMX86_SL_DEBUG
-#define vmx86_sl_debug 1
-#define SL_DEBUG_ONLY(x) x
-#else
-#define vmx86_debug 0
-#define DEBUG_ONLY(x)
-#define vmx86_sl_debug 0
-#define SL_DEBUG_ONLY(x)
-#endif
-
-#ifdef VMX86_STATS
-#define vmx86_stats 1
-#define STATS_ONLY(x) x
-#else
-#define vmx86_stats 0
-#define STATS_ONLY(x)
-#endif
-
-#ifdef VMX86_DEVEL
-#define vmx86_devel 1
-#define DEVEL_ONLY(x) x
-#else
-#define vmx86_devel 0
-#define DEVEL_ONLY(x)
-#endif
-
-#ifdef VMX86_LOG
-#define vmx86_log 1
-#define LOG_ONLY(x) x
-#else
-#define vmx86_log 0
-#define LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_VMM_SERIAL_LOGGING
-#define vmx86_vmm_serial_log 1
-#define VMM_SERIAL_LOG_ONLY(x) x
-#else
-#define vmx86_vmm_serial_log 0
-#define VMM_SERIAL_LOG_ONLY(x)
-#endif
-
-#ifdef VMX86_SERVER
-#define vmx86_server 1
-#define SERVER_ONLY(x) x
-#define HOSTED_ONLY(x)
-#else
-#define vmx86_server 0
-#define SERVER_ONLY(x)
-#define HOSTED_ONLY(x) x
-#endif
-
-#ifdef VMX86_WGS
-#define vmx86_wgs 1
-#define WGS_ONLY(x) x
-#else
-#define vmx86_wgs 0
-#define WGS_ONLY(x)
-#endif
-
-#ifdef VMKERNEL
-#define vmkernel 1
-#define VMKERNEL_ONLY(x) x
-#else
-#define vmkernel 0
-#define VMKERNEL_ONLY(x)
-#endif
-
-#ifdef _WIN32
-#define WIN32_ONLY(x) x
-#define POSIX_ONLY(x)
-#else
-#define WIN32_ONLY(x)
-#define POSIX_ONLY(x) x
-#endif
-
-#ifdef VMM
-#define VMM_ONLY(x) x
-#define USER_ONLY(x)
-#else
-#define VMM_ONLY(x)
-#define USER_ONLY(x) x
-#endif
-
-/* VMVISOR ifdef only allowed in the vmkernel */
-#ifdef VMKERNEL
-#ifdef VMVISOR
-#define vmvisor 1
-#define VMVISOR_ONLY(x) x
-#else
-#define vmvisor 0
-#define VMVISOR_ONLY(x)
-#endif
-#endif
-
-#ifdef _WIN32
-#define VMW_INVALID_HANDLE INVALID_HANDLE_VALUE
-#else
-#define VMW_INVALID_HANDLE (-1)
-#endif
-
-#ifdef _WIN32
-#define fsync(fd) _commit(fd)
-#define fileno(f) _fileno(f)
-#else
-#endif
-
-/*
- * Debug output macros for Windows drivers (the Eng variant is for
- * display/printer drivers only.
- */
-#ifdef _WIN32
-#ifndef USES_OLD_WINDDK
-#if defined(VMX86_DEBUG) || defined(ASSERT_ALWAYS_AVAILABLE)
-#define WinDrvPrint(arg, ...) DbgPrint(arg, __VA_ARGS__)
-#define WinDrvEngPrint(arg, ...) EngDbgPrint(arg, __VA_ARGS__)
-#else
-#define WinDrvPrint(arg, ...)
-#define WinDrvEngPrint(arg, ...)
-#endif
-#endif
-#endif // _WIN32
-
-#endif // ifndef _VM_BASIC_DEFS_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- *
- * vm_basic_types.h --
- *
- * basic data types.
- */
-
-
-#ifndef _VM_BASIC_TYPES_H_
-#define _VM_BASIC_TYPES_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMKDRIVERS
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMIROM
-#include "includeCheck.h"
-
-/* STRICT ANSI means the Xserver build and X defines Bool differently. */
-#if !defined(__STRICT_ANSI__) || defined(__FreeBSD__)
-typedef char Bool;
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define IsBool(x) (((x) & ~1) == 0)
-#define IsBool2(x, y) ((((x) | (y)) & ~1) == 0)
-
-/*
- * Macros __i386__ and __ia64 are intrinsically defined by GCC
- */
-#ifdef __i386__
-#define VM_I386
-#endif
-
-#ifdef _WIN64
-#define __x86_64__
-#endif
-
-#ifdef __x86_64__
-#define VM_X86_64
-#define VM_I386
-#define vm_x86_64 (1)
-#else
-#define vm_x86_64 (0)
-#endif
-
-
-
-#ifdef _WIN32
-/* safe assumption for a while */
-#define VM_I386
-#endif
-
-#ifdef _MSC_VER
-
-#pragma warning (3 :4505) // unreferenced local function
-#pragma warning (disable :4018) // signed/unsigned mismatch
-#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
-#pragma warning (disable :4305) // truncation from 'const int' to 'short'
-#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
-#pragma warning (disable :4267) // truncation of 'size_t'
-#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
-#pragma warning (disable :4142) // benign redefinition of type
-
-#endif
-
-#if defined(__APPLE__) || defined(HAVE_STDINT_H)
-
-/*
- * TODO: This is a C99 standard header. We should be able to test for
- * #if __STDC_VERSION__ >= 199901L, but that breaks the Netware build
- * (which doesn't have stdint.h).
- */
-
-#include <stdint.h>
-
-typedef uint64_t uint64;
-typedef int64_t int64;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint8_t uint8;
-
-/*
- * XXX: int8_t is defined to be 'signed char' on Mac hosts.
- *
- * Unfortunately, GCC 4.0.1 warns when doing pointer assignment or
- * comparison between signed char * and char * (even if char is
- * signed).
- *
- * If we want to use int8_t to define int8, we need to go through and
- * replace uses of char * with signed char * to prevent warnings.
- */
-typedef char int8;
-
-#else /* !HAVE_STDINT_H */
-
-#ifdef _MSC_VER
-
-typedef unsigned __int64 uint64;
-typedef signed __int64 int64;
-
-#elif __GNUC__
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-#if defined(VM_X86_64)
-typedef unsigned long uint64;
-typedef long int64;
-#else
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#elif __FreeBSD__
-typedef unsigned long long uint64;
-typedef long long int64;
-#endif
-#else
-#error - Need compiler define for int64/uint64
-#endif /* _MSC_VER */
-
-typedef unsigned int uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
-typedef int int32;
-typedef short int16;
-typedef char int8;
-
-#endif /* HAVE_STDINT_H */
-
-/*
- * FreeBSD (for the tools build) unconditionally defines these in
- * sys/inttypes.h so don't redefine them if this file has already
- * been included. [greg]
- *
- * This applies to Solaris as well.
- */
-
-/*
- * Before trying to do the includes based on OS defines, see if we can use
- * feature-based defines to get as much functionality as possible
- */
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_INTTYPES_H
-#include <sys/inttypes.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
-#endif
-
-#if !defined(USING_AUTOCONF)
-# if defined(__FreeBSD__) || defined(sun)
-# ifdef KLD_MODULE
-# include <sys/types.h>
-# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
-# include <sys/types.h>
-# else
-# include <sys/inttypes.h>
-# endif
-# endif
-# elif defined __APPLE__
-# if KERNEL
-# include <sys/unistd.h>
-# include <sys/types.h> /* mostly for size_t */
-# include <stdint.h>
-# else
-# include <unistd.h>
-# include <inttypes.h>
-# include <stdlib.h>
-# include <stdint.h>
-# endif
-# else
-# if !defined(__intptr_t_defined) && !defined(intptr_t)
-# define __intptr_t_defined
-# define intptr_t intptr_t
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef int64 intptr_t;
-# else
-typedef int32 intptr_t;
-# endif
-# endif
-# endif
-
-# ifndef _STDINT_H
-# ifdef VM_I386
-# ifdef VM_X86_64
-typedef uint64 uintptr_t;
-# else
-typedef uint32 uintptr_t;
-# endif
-# endif
-# endif
-# endif
-#endif
-
-
-/*
- * Time
- * XXX These should be cleaned up. -- edward
- */
-
-typedef int64 VmTimeType; /* Time in microseconds */
-typedef int64 VmTimeRealClock; /* Real clock kept in microseconds */
-typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */
-
-/*
- * Printf format specifiers for size_t and 64-bit number.
- * Use them like this:
- * printf("%"FMT64"d\n", big);
- *
- * FMTH is for handles/fds.
- */
-
-#ifdef _MSC_VER
- #define FMT64 "I64"
- #ifdef VM_X86_64
- #define FMTSZ "I64"
- #define FMTPD "I64"
- #define FMTH "I64"
- #else
- #define FMTSZ "I"
- #define FMTPD "I"
- #define FMTH "I"
- #endif
-#elif defined __APPLE__
- /* Mac OS hosts use the same formatters for 32- and 64-bit. */
- #define FMT64 "ll"
- #define FMTSZ "z"
- #define FMTPD "l"
- #define FMTH ""
-#elif __GNUC__
- #define FMTH ""
- #if defined(N_PLAT_NLM) || defined(sun) || \
- (defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) < 5))
- /*
- * Why (__FreeBSD__ + 0)? See bug 141008.
- * Yes, we really need to test both (__FreeBSD__ + 0) and
- * ((__FreeBSD__ + 0) < 5). No, we can't remove "+ 0" from
- * ((__FreeBSD__ + 0) < 5).
- */
- #ifdef VM_X86_64
- #define FMTSZ "l"
- #define FMTPD "l"
- #else
- #define FMTSZ ""
- #define FMTPD ""
- #endif
- #elif defined(__linux__) \
- || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \
- || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \
- || (defined(_POSIX2_VERSION) && _POSIX2_VERSION >= 200112L)
- /* BSD, Linux */
- #define FMTSZ "z"
-
- #if defined(VM_X86_64)
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #else
- /* Systems with a pre-C99 libc */
- #define FMTSZ "Z"
- #ifdef VM_X86_64
- #define FMTPD "l"
- #else
- #define FMTPD ""
- #endif
- #endif
- #ifdef VM_X86_64
- #define FMT64 "l"
- #elif defined(sun) || defined(__FreeBSD__)
- #define FMT64 "ll"
- #else
- #define FMT64 "L"
- #endif
-#else
- #error - Need compiler define for FMT64 and FMTSZ
-#endif
-
-/*
- * Suffix for 64-bit constants. Use it like this:
- * CONST64(0x7fffffffffffffff) for signed or
- * CONST64U(0x7fffffffffffffff) for unsigned.
- *
- * 2004.08.30(thutt):
- * The vmcore/asm64/gen* programs are compiled as 32-bit
- * applications, but must handle 64 bit constants. If the
- * 64-bit-constant defining macros are already defined, the
- * definition will not be overwritten.
- */
-
-#if !defined(CONST64) || !defined(CONST64U)
-#ifdef _MSC_VER
-#define CONST64(c) c##I64
-#define CONST64U(c) c##uI64
-#elif defined __APPLE__
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#elif __GNUC__
-#ifdef VM_X86_64
-#define CONST64(c) c##L
-#define CONST64U(c) c##uL
-#else
-#define CONST64(c) c##LL
-#define CONST64U(c) c##uLL
-#endif
-#else
-#error - Need compiler define for CONST64
-#endif
-#endif
-
-/*
- * Use CONST3264/CONST3264U if you want a constant to be
- * treated as a 32-bit number on 32-bit compiles and
- * a 64-bit number on 64-bit compiles. Useful in the case
- * of shifts, like (CONST3264U(1) << x), where x could be
- * more than 31 on a 64-bit compile.
- */
-
-#ifdef VM_X86_64
- #define CONST3264(a) CONST64(a)
- #define CONST3264U(a) CONST64U(a)
-#else
- #define CONST3264(a) (a)
- #define CONST3264U(a) (a)
-#endif
-
-#define MIN_INT32 ((int32)0x80000000)
-#define MAX_INT32 ((int32)0x7fffffff)
-
-#define MIN_UINT32 ((uint32)0)
-#define MAX_UINT32 ((uint32)0xffffffff)
-
-#define MIN_INT64 (CONST64(0x8000000000000000))
-#define MAX_INT64 (CONST64(0x7fffffffffffffff))
-
-#define MIN_UINT64 (CONST64U(0))
-#define MAX_UINT64 (CONST64U(0xffffffffffffffff))
-
-typedef uint8 *TCA; /* Pointer into TC (usually). */
-
-/*
- * Type big enough to hold an integer between 0..100
- */
-typedef uint8 Percent;
-#define AsPercent(v) ((Percent)(v))
-#define CHOOSE_PERCENT AsPercent(101)
-
-
-typedef uintptr_t VA;
-typedef uintptr_t VPN;
-
-typedef uint64 PA;
-typedef uint32 PPN;
-
-typedef uint64 PhysMemOff;
-typedef uint64 PhysMemSize;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 BA;
-#endif
-typedef uint32 BPN;
-typedef uint32 PageNum;
-typedef unsigned MemHandle;
-typedef int32 World_ID;
-
-#define INVALID_WORLD_ID ((World_ID)-1)
-
-typedef World_ID User_CartelID;
-#define INVALID_CARTEL_ID INVALID_WORLD_ID
-
-typedef User_CartelID User_SessionID;
-#define INVALID_SESSION_ID INVALID_CARTEL_ID
-
-typedef User_CartelID User_CartelGroupID;
-#define INVALID_CARTELGROUP_ID INVALID_CARTEL_ID
-
-typedef uint32 Worldlet_ID;
-#define INVALID_WORLDLET_ID ((Worldlet_ID)-1)
-
-/* world page number */
-typedef uint32 WPN;
-
-/* The Xserver source compiles with -ansi -pendantic */
-#ifndef __STRICT_ANSI__
-typedef uint64 MA;
-typedef uint32 MPN;
-#endif
-
-/*
- * This type should be used for variables that contain sector
- * position/quantity.
- */
-typedef uint64 SectorType;
-
-/*
- * Linear address
- */
-
-typedef uintptr_t LA;
-typedef uintptr_t LPN;
-#define LA_2_LPN(_la) ((_la) >> PAGE_SHIFT)
-#define LPN_2_LA(_lpn) ((_lpn) << PAGE_SHIFT)
-
-#define LAST_LPN ((((LA) 1) << (8 * sizeof(LA) - PAGE_SHIFT)) - 1)
-#define LAST_LPN32 ((((LA32)1) << (8 * sizeof(LA32) - PAGE_SHIFT)) - 1)
-#define LAST_LPN64 ((((LA64)1) << (8 * sizeof(LA64) - PAGE_SHIFT)) - 1)
-
-/* Valid bits in a LPN. */
-#define LPN_MASK LAST_LPN
-#define LPN_MASK32 LAST_LPN32
-#define LPN_MASK64 LAST_LPN64
-
-/*
- * On 64 bit platform, address and page number types default
- * to 64 bit. When we need to represent a 32 bit address, we use
- * types defined below.
- *
- * On 32 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint32 VA32;
-typedef uint32 VPN32;
-typedef uint32 LA32;
-typedef uint32 LPN32;
-typedef uint32 PA32;
-typedef uint32 PPN32;
-typedef uint32 MA32;
-typedef uint32 MPN32;
-
-/*
- * On 64 bit platform, the following types are the same as the
- * default types.
- */
-typedef uint64 VA64;
-typedef uint64 VPN64;
-typedef uint64 LA64;
-typedef uint64 LPN64;
-typedef uint64 PA64;
-typedef uint64 PPN64;
-typedef uint64 MA64;
-typedef uint64 MPN64;
-
-/*
- * VA typedefs for user world apps.
- */
-typedef VA32 UserVA32;
-typedef VA64 UserVA64;
-typedef UserVA64 UserVAConst; /* Userspace ptr to data that we may only read. */
-typedef UserVA32 UserVA32Const; /* Userspace ptr to data that we may only read. */
-typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */
-#ifdef VMKERNEL
-typedef UserVA64 UserVA;
-#else
-typedef void * UserVA;
-#endif
-
-
-/*
- * Maximal possible PPN value (errors too) that PhysMem can handle.
- * Must be at least as large as MAX_PPN which is the maximum PPN
- * for any region other than buserror.
- */
-#define PHYSMEM_MAX_PPN ((PPN)0xffffffff)
-#define MAX_PPN ((PPN)0x1fffffff) /* Maximal observable PPN value. */
-#define INVALID_PPN ((PPN)0xffffffff)
-
-#define INVALID_BPN ((BPN) 0x1fffffff)
-
-#define INVALID_MPN ((MPN)-1)
-#define MEMREF_MPN ((MPN)-2)
-#define RESERVED_MPN ((MPN) 0)
-/* Support 43 bits of address space. */
-#define MAX_MPN ((MPN)0x7fffffff)
-
-#define INVALID_LPN ((LPN)-1)
-#define INVALID_VPN ((VPN)-1)
-#define INVALID_LPN64 ((LPN64)-1)
-#define INVALID_PAGENUM ((PageNum)-1)
-#define INVALID_WPN ((WPN) -1)
-
-
-/*
- * Format modifier for printing VA, LA, and VPN.
- * Use them like this: Log("%#"FMTLA"x\n", laddr)
- */
-
-#if defined(VMM64) || defined(FROBOS64) || vm_x86_64 || defined __APPLE__
-# define FMTLA "l"
-# define FMTVA "l"
-# define FMTVPN "l"
-#else
-# define FMTLA ""
-# define FMTVA ""
-# define FMTVPN ""
-#endif
-
-#ifndef EXTERN
-#define EXTERN extern
-#endif
-#define CONST const
-
-
-#ifndef INLINE
-# ifdef _MSC_VER
-# define INLINE __inline
-# else
-# define INLINE inline
-# endif
-#endif
-
-
-/*
- * Annotation for data that may be exported into a DLL and used by other
- * apps that load that DLL and import the data.
- */
-#if defined(_WIN32) && defined(VMX86_IMPORT_DLLDATA)
-# define VMX86_EXTERN_DATA extern __declspec(dllimport)
-#else // !_WIN32
-# define VMX86_EXTERN_DATA extern
-#endif
-
-#if defined(_WIN32) && !defined(VMX86_NO_THREADS)
-#define THREADSPECIFIC __declspec(thread)
-#else
-#define THREADSPECIFIC
-#endif
-
-/*
- * Due to the wonderful "registry redirection" feature introduced in
- * 64-bit Windows, if you access any key under HKLM\Software in 64-bit
- * code, you need to open/create/delete that key with
- * VMKEY_WOW64_32KEY if you want a consistent view with 32-bit code.
- */
-
-#ifdef _WIN32
-#ifdef _WIN64
-#define VMW_KEY_WOW64_32KEY KEY_WOW64_32KEY
-#else
-#define VMW_KEY_WOW64_32KEY 0x0
-#endif
-#endif
-
-
-/*
- * Consider the following reasons functions are inlined:
- *
- * 1) inlined for performance reasons
- * 2) inlined because it's a single-use function
- *
- * Functions which meet only condition 2 should be marked with this
- * inline macro; It is not critical to be inlined (but there is a
- * code-space & runtime savings by doing so), so when other callers
- * are added the inline-ness should be removed.
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-/*
- * Starting at version 3.3, gcc does not always inline functions marked
- * 'inline' (it depends on their size). To force gcc to do so, one must use the
- * extra __always_inline__ attribute.
- */
-# define INLINE_SINGLE_CALLER INLINE __attribute__((__always_inline__))
-# if defined(VMM) \
- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
-# warning Verify INLINE_SINGLE_CALLER '__always_inline__' attribute (did \
- monitor size change?)
-# endif
-#else
-# define INLINE_SINGLE_CALLER INLINE
-#endif
-
-/*
- * Used when a hard guaranteed of no inlining is needed. Very few
- * instances need this since the absence of INLINE is a good hint
- * that gcc will not do inlining.
- */
-
-#if defined(__GNUC__) && defined(VMM)
-#define ABSOLUTELY_NOINLINE __attribute__((__noinline__))
-#endif
-
-/*
- * Attributes placed on function declarations to tell the compiler
- * that the function never returns.
- */
-
-#ifdef _MSC_VER
-#define NORETURN __declspec(noreturn)
-#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9)
-#define NORETURN __attribute__((__noreturn__))
-#else
-#define NORETURN
-#endif
-
-/*
- * GCC 3.2 inline asm needs the + constraint for input/ouput memory operands.
- * Older GCCs don't know about it --hpreg
- */
-
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
-# define VM_ASM_PLUS 1
-#else
-# define VM_ASM_PLUS 0
-#endif
-
-/*
- * Branch prediction hints:
- * LIKELY(exp) - Expression exp is likely TRUE.
- * UNLIKELY(exp) - Expression exp is likely FALSE.
- * Usage example:
- * if (LIKELY(excCode == EXC_NONE)) {
- * or
- * if (UNLIKELY(REAL_MODE(vc))) {
- *
- * We know how to predict branches on gcc3 and later (hopefully),
- * all others we don't so we do nothing.
- */
-
-#if (__GNUC__ >= 3)
-/*
- * gcc3 uses __builtin_expect() to inform the compiler of an expected value.
- * We use this to inform the static branch predictor. The '!!' in LIKELY
- * will convert any !=0 to a 1.
- */
-#define LIKELY(_exp) __builtin_expect(!!(_exp), 1)
-#define UNLIKELY(_exp) __builtin_expect((_exp), 0)
-#else
-#define LIKELY(_exp) (_exp)
-#define UNLIKELY(_exp) (_exp)
-#endif
-
-/*
- * GCC's argument checking for printf-like functions
- * This is conditional until we have replaced all `"%x", void *'
- * with `"0x%08x", (uint32) void *'. Note that %p prints different things
- * on different platforms. Argument checking is enabled for the
- * vmkernel, which has already been cleansed.
- *
- * fmtPos is the position of the format string argument, beginning at 1
- * varPos is the position of the variable argument, beginning at 1
- */
-
-#if defined(__GNUC__)
-# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
-#else
-# define PRINTF_DECL(fmtPos, varPos)
-#endif
-
-#if defined(__GNUC__)
-# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
-#else
-# define SCANF_DECL(fmtPos, varPos)
-#endif
-
-/*
- * UNUSED_PARAM should surround the parameter name and type declaration,
- * e.g. "int MyFunction(int var1, UNUSED_PARAM(int var2))"
- *
- */
-
-#ifndef UNUSED_PARAM
-# if defined(__GNUC__)
-# define UNUSED_PARAM(_parm) _parm __attribute__((__unused__))
-# else
-# define UNUSED_PARAM(_parm) _parm
-# endif
-#endif
-
-/*
- * REGPARM defaults to REGPARM3, i.e., a requent that gcc
- * puts the first three arguments in registers. (It is fine
- * if the function has fewer than three args.) Gcc only.
- * Syntactically, put REGPARM where you'd put INLINE or NORETURN.
- */
-
-#if defined(__GNUC__)
-# define REGPARM0 __attribute__((regparm(0)))
-# define REGPARM1 __attribute__((regparm(1)))
-# define REGPARM2 __attribute__((regparm(2)))
-# define REGPARM3 __attribute__((regparm(3)))
-# define REGPARM REGPARM3
-#else
-# define REGPARM0
-# define REGPARM1
-# define REGPARM2
-# define REGPARM3
-# define REGPARM
-#endif
-
-/*
- * ALIGNED specifies minimum alignment in "n" bytes.
- */
-
-#ifdef __GNUC__
-#define ALIGNED(n) __attribute__((__aligned__(n)))
-#else
-#define ALIGNED(n)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_OFFSET_CHECK -- */ /**
- *
- * \brief Check if the actual offsef of a member in a structure
- * is what is expected
- *
- *
- * \param[in] STRUCT Structure the member is a part of.
- * \param[in] MEMBER Member to check the offset of.
- * \param[in] OFFSET Expected offset of MEMBER in STRUCTURE.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to OFFSET to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == (OFFSET + DEBUG_EXTRA))
-#else
-#define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == OFFSET)
-#endif
-
-/*
- ***********************************************************************
- * STRUCT_SIZE_CHECK -- */ /**
- *
- * \brief Check if the actual size of a structure is what is expected
- *
- *
- * \param[in] STRUCT Structure whose size is to be checked.
- * \param[in] SIZE Expected size of STRUCT.
- * \param[in] DEBUG_EXTRA Additional bytes to be added to SIZE to
- * compensate for extra info in debug builds.
- *
- ***********************************************************************
- */
-#ifdef VMX86_DEBUG
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == (SIZE + DEBUG_EXTRA))
-#else
-#define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \
- ASSERT_ON_COMPILE(sizeof(STRUCT) == SIZE)
-#endif
-
-/*
- * __func__ is a stringified function name that is part of the C99 standard. The block
- * below defines __func__ on older systems where the compiler does not support that
- * macro.
- */
-#if defined(__GNUC__) \
- && ((__GNUC__ == 2 && __GNUC_MINOR < 96) \
- || (__GNUC__ < 2))
-# define __func__ __FUNCTION__
-#endif
-
-/*
- * Once upon a time, this was used to silence compiler warnings that
- * get generated when the compiler thinks that a function returns
- * when it is marked noreturn. Don't do it. Use NOT_REACHED().
- */
-
-#define INFINITE_LOOP() do { } while (1)
-
-/*
- * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_
- * is defined. Use the same logic here so we don't define it twice. [greg]
- */
-#ifdef __FreeBSD__
-# ifdef _BSD_SIZE_T_
-# undef _BSD_SIZE_T_
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# ifdef _BSD_SSIZE_T_
-# undef _BSD_SSIZE_T_
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#else
-# ifndef _SIZE_T
-# define _SIZE_T
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef uint64 size_t;
-# else
- typedef uint32 size_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-# if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(ssize_t) && \
- !defined(__ssize_t_defined) && !defined(_SSIZE_T_DECLARED)
-# define _SSIZE_T
-# define __ssize_t_defined
-# define _SSIZE_T_DECLARED
-# ifdef VM_I386
-# ifdef VM_X86_64
- typedef int64 ssize_t;
-# else
- typedef int32 ssize_t;
-# endif
-# endif /* VM_I386 */
-# endif
-
-#endif
-
-/*
- * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The pid is %"FMTPID".\n", pid);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTPID "d"
-# else
-# define FMTPID "lu"
-# endif
-#else
-# define FMTPID "d"
-#endif
-
-/*
- * Format modifier for printing uid_t. On Solaris 10 and earlier, uid_t
- * is a ulong, but on other platforms it's an unsigned int.
- * Use this like this: printf("The uid is %"FMTUID".\n", uid);
- */
-#if defined(sun) && !defined(SOL11)
-# ifdef VM_X86_64
-# define FMTUID "u"
-# else
-# define FMTUID "lu"
-# endif
-#else
-# define FMTUID "u"
-#endif
-
-/*
- * Format modifier for printing mode_t. On sun the mode_t is a ulong, but on
- * Linux it's an int.
- * Use this like this: printf("The mode is %"FMTMODE".\n", mode);
- */
-#ifdef sun
-# ifdef VM_X86_64
-# define FMTMODE "o"
-# else
-# define FMTMODE "lo"
-# endif
-#else
-# define FMTMODE "o"
-#endif
-
-/*
- * Format modifier for printing time_t. Most platforms define a time_t to be
- * a long int, but on FreeBSD (as of 5.0, it seems), the time_t is a signed
- * size quantity. Refer to the definition of FMTSZ to see why we need silly
- * preprocessor arithmetic.
- * Use this like this: printf("The mode is %"FMTTIME".\n", time);
- */
-#if defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) >= 5)
-# define FMTTIME FMTSZ"d"
-#else
-# define FMTTIME "ld"
-#endif
-
-/*
- * Define MXSemaHandle here so both vmmon and vmx see this definition.
- */
-
-#ifdef _WIN32
-typedef uintptr_t MXSemaHandle;
-#else
-typedef int MXSemaHandle;
-#endif
-
-/*
- * Define type for poll device handles.
- */
-
-#ifdef _WIN32
-typedef uintptr_t PollDevHandle;
-#else
-typedef int PollDevHandle;
-#endif
-
-/*
- * Define the utf16_t type.
- */
-
-#if defined(_WIN32) && defined(_NATIVE_WCHAR_T_DEFINED)
-typedef wchar_t utf16_t;
-#else
-typedef uint16 utf16_t;
-#endif
-
-#endif /* _VM_BASIC_TYPES_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmciGuestKernelAPI.h --
- *
- * Kernel API exported from the VMCI guest driver.
- */
-
-#ifndef __VMCI_GUESTKERNELAPI_H__
-#define __VMCI_GUESTKERNELAPI_H__
-
-/* VMCI guest kernel API version number. */
-#define VMCI_GUEST_KERNEL_API_VERSION 1
-
-/* Macros to operate on the driver version number. */
-#define VMCI_MAJOR_VERSION(v) (((v) >> 16) & 0xffff)
-#define VMCI_MINOT_VERSION(v) ((v) & 0xffff)
-
-#define INCLUDE_ALLOW_MODULE
-#include "includeCheck.h"
-
-#include "vmci_defs.h"
-#include "vmci_call_defs.h"
-
-#include "vmci_queue_pair.h"
-
-/* VMCI Device Usage API. */
-Bool VMCI_DeviceGet(void);
-void VMCI_DeviceRelease(void);
-
-/* VMCI Datagram API. */
-int VMCIDatagram_CreateHnd(VMCIId resourceID, uint32 flags,
- VMCIDatagramRecvCB recvCB, void *clientData,
- VMCIHandle *outHandle);
-int VMCIDatagram_DestroyHnd(VMCIHandle handle);
-int VMCIDatagram_Send(VMCIDatagram *msg);
-
-/* VMCI Utility API. */
-VMCIId VMCI_GetContextID(void);
-uint32 VMCI_Version(void);
-
-/* VMCI Event API. */
-
-typedef void (*VMCI_EventCB)(VMCIId subID, VMCI_EventData *ed,
- void *clientData);
-
-int VMCIEvent_Subscribe(VMCI_Event event, VMCI_EventCB callback,
- void *callbackData, VMCIId *subID);
-int VMCIEvent_Unsubscribe(VMCIId subID);
-
-/* VMCI Discovery Service API. */
-int VMCIDs_Lookup(const char *name, VMCIHandle *out);
-
-int VMCIQueuePair_Alloc(VMCIHandle *handle, VMCIQueue **produceQ,
- uint64 produceSize, VMCIQueue **consumeQ,
- uint64 consumeSize, VMCIId peer, uint32 flags);
-int VMCIQueuePair_Detach(VMCIHandle handle);
-
-#endif /* !__VMCI_GUESTKERNELAPI_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006-2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef _VMCI_CALL_DEFS_H_
-#define _VMCI_CALL_DEFS_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMKMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-#include "vmci_defs.h"
-
-/*
- * All structs here are an integral size of their largest member, ie. a struct
- * with at least one 8-byte member will have a size that is an integral of 8.
- * A struct which has a largest member of size 4 will have a size that is an
- * integral of 4. This is because Windows CL enforces this rule. 32 bit gcc
- * doesn't e.g. 32 bit gcc can misalign an 8 byte member if it is preceeded by
- * a 4 byte member.
- */
-
-/*
- * Base struct for vmci datagrams.
- */
-
-typedef struct VMCIDatagram {
- VMCIHandle dst;
- VMCIHandle src;
- uint64 payloadSize;
-} VMCIDatagram;
-
-
-/* Flag for creating a wellknown handle instead of a per context handle. */
-#define VMCI_FLAG_WELLKNOWN_DG_HND 0x1
-
-/*
- * Maximum supported size of a VMCI datagram for routable datagrams.
- * Datagrams going to the hypervisor are allowed to be larger.
- */
-#define VMCI_MAX_DG_SIZE (17 * 4096)
-#define VMCI_MAX_DG_PAYLOAD_SIZE (VMCI_MAX_DG_SIZE - sizeof(VMCIDatagram))
-#define VMCI_DG_PAYLOAD(_dg) (void *)((char *)(_dg) + sizeof(VMCIDatagram))
-#define VMCI_DG_HEADERSIZE sizeof(VMCIDatagram)
-#define VMCI_DG_SIZE(_dg) (VMCI_DG_HEADERSIZE + (size_t)(_dg)->payloadSize)
-#define VMCI_DG_SIZE_ALIGNED(_dg) ((VMCI_DG_SIZE(_dg) + 7) & (size_t)CONST64U(0xfffffffffffffff8))
-#define VMCI_MAX_DATAGRAM_QUEUE_SIZE (VMCI_MAX_DG_SIZE * 2)
-
-/*
- * Struct for sending VMCI_DATAGRAM_REQUEST_MAP and VMCI_DATAGRAM_REMOVE_MAP
- * datagrams. Struct size is 32 bytes. All fields in struct are aligned to
- * their natural alignment.
- */
-typedef struct VMCIDatagramWellKnownMapMsg {
- VMCIDatagram hdr;
- VMCIId wellKnownID;
- uint32 _pad;
-} VMCIDatagramWellKnownMapMsg;
-
-
-/*
- * Struct used for querying, via VMCI_RESOURCES_QUERY, the availability of
- * hypervisor resources.
- * Struct size is 16 bytes. All fields in struct are aligned to their natural
- * alignment.
- */
-typedef struct VMCIResourcesQueuryHdr {
- VMCIDatagram hdr;
- uint32 numResources;
- uint32 _padding;
-} VMCIResourcesQueryHdr;
-
-
-/*
- * Convenience struct for negotiating vectors. Must match layout of
- * VMCIResourceQueryHdr minus the VMCIDatagram header.
- */
-typedef struct VMCIResourcesQueryMsg {
- uint32 numResources;
- uint32 _padding;
- VMCI_Resource resources[1];
-} VMCIResourcesQueryMsg;
-
-
-/*
- * The maximum number of resources that can be queried using
- * VMCI_RESOURCE_QUERY is 31, as the result is encoded in the lower 31
- * bits of a positive return value. Negative values are reserved for
- * errors.
- */
-#define VMCI_RESOURCE_QUERY_MAX_NUM 31
-
-/* Maximum size for the VMCI_RESOURCE_QUERY request. */
-#define VMCI_RESOURCE_QUERY_MAX_SIZE sizeof(VMCIResourcesQueryHdr) \
- + VMCI_RESOURCE_QUERY_MAX_NUM * sizeof(VMCI_Resource)
-
-/*
- * Struct used for making VMCI_SHAREDMEM_CREATE message. Struct size is 24 bytes.
- * All fields in struct are aligned to their natural alignment.
- */
-typedef struct VMCISharedMemCreateMsg {
- VMCIDatagram hdr;
- VMCIHandle handle;
- uint32 memSize;
- uint32 _padding;
- /* PPNs placed after struct. */
-} VMCISharedMemCreateMsg;
-
-
-/*
- * Struct used for sending VMCI_SHAREDMEM_ATTACH messages. Same as struct used
- * for create messages.
- */
-typedef VMCISharedMemCreateMsg VMCISharedMemAttachMsg;
-
-
-/*
- * Struct used for sending VMCI_SHAREDMEM_DETACH messsages. Struct size is 16
- * bytes. All fields in struct are aligned to their natural alignment.
- */
-typedef struct VMCISharedMemDetachMsg {
- VMCIDatagram hdr;
- VMCIHandle handle;
-} VMCISharedMemDetachMsg;
-
-
-/*
- * Struct used for sending VMCI_SHAREDMEM_QUERY messages. Same as struct used
- * for detach messages.
- */
-typedef VMCISharedMemDetachMsg VMCISharedMemQueryMsg;
-
-
-/*
- * This struct is used to contain data for events. Size of this struct is a
- * multiple of 8 bytes, and all fields are aligned to their natural alignment.
- */
-typedef struct VMCI_EventData {
- VMCI_Event event; /* 4 bytes. */
- uint32 _pad;
- /*
- * Event payload is put here.
- */
-} VMCI_EventData;
-
-
-/* Callback needed for correctly waiting on events. */
-
-typedef int
-(*VMCIDatagramRecvCB)(void *clientData, // IN: client data for handler
- VMCIDatagram *msg); // IN:
-
-
-/*
- * We use the following inline function to access the payload data associated
- * with an event data.
- */
-
-static INLINE void *
-VMCIEventDataPayload(VMCI_EventData *evData) // IN:
-{
- return (void *)((char *)evData + sizeof *evData);
-}
-
-/*
- * Define the different VMCI_EVENT payload data types here. All structs must
- * be a multiple of 8 bytes, and fields must be aligned to their natural
- * alignment.
- */
-typedef struct VMCIEventPayload_Context {
- VMCIId contextID; /* 4 bytes. */
- uint32 _pad;
-} VMCIEventPayload_Context;
-
-typedef struct VMCIEventPayload_QP {
- VMCIHandle handle; /* QueuePair handle. */
- VMCIId peerId; /* Context id of attaching/detaching VM. */
- uint32 _pad;
-} VMCIEventPayload_QP;
-
-/*
- * We define the following struct to get the size of the maximum event data
- * the hypervisor may send to the guest. If adding a new event payload type
- * above, add it to the following struct too (inside the union).
- */
-typedef struct VMCIEventData_Max {
- VMCI_EventData eventData;
- union {
- VMCIEventPayload_Context contextPayload;
- VMCIEventPayload_QP qpPayload;
- } evDataPayload;
-} VMCIEventData_Max;
-
-
-/*
- * Struct used for VMCI_EVENT_SUBSCRIBE/UNSUBSCRIBE and VMCI_EVENT_HANDLER
- * messages. Struct size is 32 bytes. All fields in struct are aligned to
- * their natural alignment.
- */
-typedef struct VMCIEventMsg {
- VMCIDatagram hdr;
- VMCI_EventData eventData; /* Has event type and payload. */
- /*
- * Payload gets put here.
- */
-} VMCIEventMsg;
-
-
-/*
- * We use the following inline function to access the payload data associated
- * with an event message.
- */
-
-static INLINE void *
-VMCIEventMsgPayload(VMCIEventMsg *eMsg) // IN:
-{
- return VMCIEventDataPayload(&eMsg->eventData);
-}
-
-
-/* Flags for VMCI QueuePair API. */
-#define VMCI_QPFLAG_ATTACH_ONLY 0x1 /* Fail alloc if QP not created by peer. */
-#define VMCI_QPFLAG_LOCAL 0x2 /* Only allow attaches from local context. */
-/* Update the following (bitwise OR flags) while adding new flags. */
-#define VMCI_QP_ALL_FLAGS (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QPFLAG_LOCAL)
-
-/*
- * Structs used for QueuePair alloc and detach messages. We align fields of
- * these structs to 64bit boundaries.
- */
-
-typedef struct VMCIQueuePairAllocMsg {
- VMCIDatagram hdr;
- VMCIHandle handle;
- VMCIId peer; /* 32bit field. */
- uint32 flags;
- uint64 produceSize;
- uint64 consumeSize;
- uint64 numPPNs;
- /* List of PPNs placed here. */
-} VMCIQueuePairAllocMsg;
-
-
-typedef struct VMCIQueuePairDetachMsg {
- VMCIDatagram hdr;
- VMCIHandle handle;
-} VMCIQueuePairDetachMsg;
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2005-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef _VMCI_DEF_H_
-#define _VMCI_DEF_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-
-/* Register offsets. */
-#define VMCI_STATUS_ADDR 0x00
-#define VMCI_CONTROL_ADDR 0x04
-#define VMCI_ICR_ADDR 0x08
-#define VMCI_IMR_ADDR 0x0c
-#define VMCI_DATA_OUT_ADDR 0x10
-#define VMCI_DATA_IN_ADDR 0x14
-#define VMCI_CAPS_ADDR 0x18
-#define VMCI_RESULT_LOW_ADDR 0x1c
-#define VMCI_RESULT_HIGH_ADDR 0x20
-
-/* Max number of devices. */
-#define VMCI_MAX_DEVICES 1
-
-/* Status register bits. */
-#define VMCI_STATUS_INT_ON 0x1
-
-/* Control register bits. */
-#define VMCI_CONTROL_RESET 0x1
-#define VMCI_CONTROL_INT_ENABLE 0x2
-#define VMCI_CONTROL_INT_DISABLE 0x4
-
-/* Capabilities register bits. */
-#define VMCI_CAPS_HYPERCALL 0x1
-#define VMCI_CAPS_GUESTCALL 0x2
-#define VMCI_CAPS_DATAGRAM 0x4
-
-/* Interrupt Cause register bits. */
-#define VMCI_ICR_DATAGRAM 0x1
-
-/* Interrupt Mask register bits. */
-#define VMCI_IMR_DATAGRAM 0x1
-
-/*
- * We have a fixed set of resource IDs available in the VMX.
- * This allows us to have a very simple implementation since we statically
- * know how many will create datagram handles. If a new caller arrives and
- * we have run out of slots we can manually increment the maximum size of
- * available resource IDs.
- */
-
-typedef uint32 VMCI_Resource;
-
-/* VMCI reserved hypervisor datagram resource IDs. */
-#define VMCI_RESOURCES_QUERY 0
-#define VMCI_GET_CONTEXT_ID 1
-#define VMCI_SHAREDMEM_CREATE 2
-#define VMCI_SHAREDMEM_ATTACH 3
-#define VMCI_SHAREDMEM_DETACH 4
-#define VMCI_SHAREDMEM_QUERY 5
-#define VMCI_DATAGRAM_REQUEST_MAP 6
-#define VMCI_DATAGRAM_REMOVE_MAP 7
-#define VMCI_EVENT_SUBSCRIBE 8
-#define VMCI_EVENT_UNSUBSCRIBE 9
-#define VMCI_QUEUEPAIR_ALLOC 10
-#define VMCI_QUEUEPAIR_DETACH 11
-#define VMCI_RESOURCE_MAX 12
-
-/* VMCI Ids. */
-typedef uint32 VMCIId;
-
-typedef struct VMCIHandle {
- VMCIId context;
- VMCIId resource;
-} VMCIHandle;
-
-static INLINE
-VMCIHandle VMCI_MAKE_HANDLE(VMCIId cid,
- VMCIId rid)
-{
- VMCIHandle h = {cid, rid};
- return h;
-}
-
-#define VMCI_HANDLE_TO_CONTEXT_ID(_handle) ((_handle).context)
-#define VMCI_HANDLE_TO_RESOURCE_ID(_handle) ((_handle).resource)
-#define VMCI_HANDLE_EQUAL(_h1, _h2) ((_h1).context == (_h2).context && \
- (_h1).resource == (_h2).resource)
-
-#define VMCI_INVALID_ID 0xFFFFFFFF
-static const VMCIHandle VMCI_INVALID_HANDLE = {VMCI_INVALID_ID,
- VMCI_INVALID_ID};
-
-#define VMCI_HANDLE_INVALID(_handle) \
- VMCI_HANDLE_EQUAL((_handle), VMCI_INVALID_HANDLE)
-
-/*
- * The below defines can be used to send anonymous requests.
- * This also indicates that no response is expected.
- */
-#define VMCI_ANON_SRC_CONTEXT_ID VMCI_INVALID_ID
-#define VMCI_ANON_SRC_RESOURCE_ID VMCI_INVALID_ID
-#define VMCI_ANON_SRC_HANDLE VMCI_MAKE_HANDLE(VMCI_ANON_SRC_CONTEXT_ID, \
- VMCI_ANON_SRC_RESOURCE_ID)
-
-/* The lowest 16 context ids are reserved for internal use. */
-#define VMCI_RESERVED_CID_LIMIT 16
-
-/*
- * Hypervisor context id, used for calling into hypervisor
- * supplied services from the VM.
- */
-#define VMCI_HYPERVISOR_CONTEXT_ID 0
-
-/*
- * Well-known context id, a logical context that contains
- * a set of well-known services.
- */
-#define VMCI_WELL_KNOWN_CONTEXT_ID 1
-
-/* Todo: Change host context id to dynamic/random id. */
-#define VMCI_HOST_CONTEXT_ID 2
-
-/*
- * The VMCI_CONTEXT_RESOURCE_ID is used together with VMCI_MAKE_HANDLE to make
- * handles that refer to a specific context.
- */
-#define VMCI_CONTEXT_RESOURCE_ID 0
-
-
-/* VMCI error codes. */
-#define VMCI_SUCCESS_QUEUEPAIR_ATTACH 5
-#define VMCI_SUCCESS_QUEUEPAIR_CREATE 4
-#define VMCI_SUCCESS_LAST_DETACH 3
-#define VMCI_SUCCESS_ACCESS_GRANTED 2
-#define VMCI_SUCCESS_ENTRY_DEAD 1
-#define VMCI_SUCCESS 0
-#define VMCI_ERROR_INVALID_RESOURCE (-1)
-#define VMCI_ERROR_INVALID_ARGS (-2)
-#define VMCI_ERROR_NO_MEM (-3)
-#define VMCI_ERROR_DATAGRAM_FAILED (-4)
-#define VMCI_ERROR_MORE_DATA (-5)
-#define VMCI_ERROR_NO_MORE_DATAGRAMS (-6)
-#define VMCI_ERROR_NO_ACCESS (-7)
-#define VMCI_ERROR_NO_HANDLE (-8)
-#define VMCI_ERROR_DUPLICATE_ENTRY (-9)
-#define VMCI_ERROR_DST_UNREACHABLE (-10)
-#define VMCI_ERROR_PAYLOAD_TOO_LARGE (-11)
-#define VMCI_ERROR_INVALID_PRIV (-12)
-#define VMCI_ERROR_GENERIC (-13)
-#define VMCI_ERROR_PAGE_ALREADY_SHARED (-14)
-#define VMCI_ERROR_CANNOT_SHARE_PAGE (-15)
-#define VMCI_ERROR_CANNOT_UNSHARE_PAGE (-16)
-#define VMCI_ERROR_NO_PROCESS (-17)
-#define VMCI_ERROR_NO_DATAGRAM (-18)
-#define VMCI_ERROR_NO_RESOURCES (-19)
-#define VMCI_ERROR_UNAVAILABLE (-20)
-#define VMCI_ERROR_NOT_FOUND (-21)
-#define VMCI_ERROR_ALREADY_EXISTS (-22)
-#define VMCI_ERROR_NOT_PAGE_ALIGNED (-23)
-#define VMCI_ERROR_INVALID_SIZE (-24)
-#define VMCI_ERROR_REGION_ALREADY_SHARED (-25)
-#define VMCI_ERROR_TIMEOUT (-26)
-#define VMCI_ERROR_DATAGRAM_INCOMPLETE (-27)
-#define VMCI_ERROR_INCORRECT_IRQL (-28)
-#define VMCI_ERROR_EVENT_UNKNOWN (-29)
-#define VMCI_ERROR_OBSOLETE (-30)
-#define VMCI_ERROR_QUEUEPAIR_MISMATCH (-31)
-#define VMCI_ERROR_QUEUEPAIR_NOTSET (-32)
-#define VMCI_ERROR_QUEUEPAIR_NOTOWNER (-33)
-#define VMCI_ERROR_QUEUEPAIR_NOTATTACHED (-34)
-#define VMCI_ERROR_QUEUEPAIR_NOSPACE (-35)
-#define VMCI_ERROR_QUEUEPAIR_NODATA (-36)
-#define VMCI_ERROR_BUSMEM_INVALIDATION (-37)
-#define VMCI_ERROR_MODULE_NOT_LOADED (-38)
-
-/* Internal error codes. */
-#define VMCI_SHAREDMEM_ERROR_BAD_CONTEXT (-1000)
-
-#define VMCI_PATH_MAX 256
-
-/* VMCI reserved events. */
-typedef uint32 VMCI_Event;
-
-#define VMCI_EVENT_CTX_ID_UPDATE 0
-#define VMCI_EVENT_CTX_REMOVED 1
-#define VMCI_EVENT_QP_RESUMED 2
-#define VMCI_EVENT_QP_PEER_ATTACH 3
-#define VMCI_EVENT_QP_PEER_DETACH 4
-#define VMCI_EVENT_MAX 5
-
-/* Reserved guest datagram resource ids. */
-#define VMCI_EVENT_HANDLER 0
-
-/* VMCI privileges. */
-typedef enum VMCIResourcePrivilegeType {
- VMCI_PRIV_CH_PRIV,
- VMCI_PRIV_DESTROY_RESOURCE,
- VMCI_PRIV_ASSIGN_CLIENT,
- VMCI_PRIV_DG_CREATE,
- VMCI_PRIV_DG_SEND,
- VMCI_PRIV_SM_CREATE,
- VMCI_PRIV_SM_ATTACH,
- VMCI_NUM_PRIVILEGES,
-} VMCIResourcePrivilegeType;
-
-/*
- * VMCI coarse-grained privileges (per context or host
- * process/endpoint. An entity with the restricted flag is only
- * allowed to interact with the hypervisor and trusted entities.
- */
-typedef uint32 VMCIPrivilegeFlags;
-
-#define VMCI_PRIVILEGE_FLAG_RESTRICTED 0x01
-#define VMCI_PRIVILEGE_FLAG_TRUSTED 0x02
-#define VMCI_PRIVILEGE_ALL_FLAGS (VMCI_PRIVILEGE_FLAG_RESTRICTED | \
- VMCI_PRIVILEGE_FLAG_TRUSTED)
-#define VMCI_NO_PRIVILEGE_FLAGS 0x00
-#define VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS VMCI_NO_PRIVILEGE_FLAGS
-#define VMCI_LEAST_PRIVILEGE_FLAGS VMCI_PRIVILEGE_FLAG_RESTRICTED
-#define VMCI_MAX_PRIVILEGE_FLAGS VMCI_PRIVILEGE_FLAG_TRUSTED
-
-/* VMCI Discovery Service. */
-
-/* Well-known handle to the discovery service. */
-#define VMCI_DS_RESOURCE_ID 1 /* Reserved resource ID for discovery service. */
-#define VMCI_DS_HANDLE VMCI_MAKE_HANDLE(VMCI_WELL_KNOWN_CONTEXT_ID, \
- VMCI_DS_RESOURCE_ID)
-#define VMCI_DS_CONTEXT VMCI_MAKE_HANDLE(VMCI_WELL_KNOWN_CONTEXT_ID, \
- VMCI_CONTEXT_RESOURCE_ID)
-
-/* Maximum length of a DS message. */
-#define VMCI_DS_MAX_MSG_SIZE 300
-
-/* Command actions. */
-#define VMCI_DS_ACTION_LOOKUP 0
-#define VMCI_DS_ACTION_REGISTER 1
-#define VMCI_DS_ACTION_UNREGISTER 2
-
-/* Defines wire-protocol format for a request send to the DS from a context. */
-typedef struct VMCIDsRequestHeader {
- int32 action;
- int32 msgid;
- VMCIHandle handle;
- int32 nameLen;
- int8 name[1];
-} VMCIDsRequestHeader;
-
-
-/* Defines the wire-protocol format for a request send from the DS to a context. */
-typedef struct VMCIDsReplyHeader {
- int32 msgid;
- int32 code;
- VMCIHandle handle;
- int32 msgLen;
- int8 msg[1];
-} VMCIDsReplyHeader;
-
-#define VMCI_PUBLIC_GROUP_NAME "vmci public group"
-/* 0 through VMCI_RESERVED_RESOURCE_ID_MAX are reserved. */
-#define VMCI_RESERVED_RESOURCE_ID_MAX 1023
-
-#define VMCI_DOMAIN_NAME_MAXLEN 32
-
-#define VMCI_LGPFX "VMCI: "
-
-#endif
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmci_infrastructure.h --
- *
- * This file implements the VMCI infrastructure.
- */
-
-#ifndef _VMCI_INFRASTRUCTURE_H_
-#define _VMCI_INFRASTRUCTURE_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-#include "vmware.h"
-#include "vmci_defs.h"
-
-typedef enum {
- VMCIOBJ_VMX_VM = 10,
- VMCIOBJ_CONTEXT,
- VMCIOBJ_PROCESS,
- VMCIOBJ_DATAGRAM_PROCESS,
- VMCIOBJ_NOT_SET,
-} VMCIObjType;
-
-/* Guestcalls currently support a maximum of 8 uint64 arguments. */
-#define VMCI_GUESTCALL_MAX_ARGS_SIZE 64
-
-/* Used to determine what checkpoint state to get and set. */
-#define VMCI_NOTIFICATION_CPT_STATE 0x1
-#define VMCI_WELLKNOWN_CPT_STATE 0x2
-#define VMCI_QP_CPT_STATE 0x3
-#define VMCI_QP_INFO_CPT_STATE 0x4
-
-/* Used to control the VMCI device in the vmkernel */
-#define VMCI_DEV_RESET 0x01
-#define VMCI_DEV_QP_RESET 0x02
-#define VMCI_DEV_QUIESCE 0x03
-#define VMCI_DEV_UNQUIESCE 0x04
-#define VMCI_DEV_QP_BREAK_SHARING 0x05
-
-/*
- *-------------------------------------------------------------------------
- *
- * VMCI_Hash --
- *
- * Hash function used by the Simple Datagram API. Based on the djb2
- * hash function by Dan Bernstein.
- *
- * Result:
- * Returns guest call size.
- *
- * Side effects:
- * None.
- *
- *-------------------------------------------------------------------------
- */
-
-static INLINE int
-VMCI_Hash(VMCIHandle handle, // IN
- unsigned size) // IN
-{
- unsigned i;
- int hash = 5381;
- const uint64 handleValue = QWORD(handle.resource, handle.context);
-
- for (i = 0; i < sizeof handle; i++) {
- hash = ((hash << 5) + hash) + (uint8)(handleValue >> (i * 8));
- }
- return hash & (size - 1);
-}
-
-#endif // _VMCI_INFRASTRUCTURE_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-
-/*
- * vmci_iocontrols.h
- *
- * The VMCI driver io controls.
- */
-
-#ifndef _VMCI_IOCONTROLS_H_
-#define _VMCI_IOCONTROLS_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#include "includeCheck.h"
-
-#include "vmci_defs.h"
-
-/*
- * Driver version.
- *
- * Increment major version when you make an incompatible change.
- * Compatibility goes both ways (old driver with new executable
- * as well as new driver with old executable).
- */
-
-#define VMCI_VERSION_SHIFT_WIDTH 16 /* Never change this. */
-#define VMCI_MAJOR_VERSION_VALUE 8 /* Bump major version number here. */
-#define VMCI_MINOR_VERSION_VALUE 0 /* Bump minor version number here. */
-
-/* Don't modify the next three macros. */
-#define VMCI_VERSION (VMCI_MAJOR_VERSION_VALUE << \
- VMCI_VERSION_SHIFT_WIDTH | \
- VMCI_MINOR_VERSION_VALUE)
-#define VMCI_VERSION_MAJOR(v) ((uint32) (v) >> VMCI_VERSION_SHIFT_WIDTH)
-#define VMCI_VERSION_MINOR(v) ((uint16) (v))
-
-#if defined(__linux__) || defined(__APPLE__) || defined(SOLARIS) || defined(VMKERNEL)
-/*
- * Linux defines _IO* macros, but the core kernel code ignore the encoded
- * ioctl value. It is up to individual drivers to decode the value (for
- * example to look at the size of a structure to determine which version
- * of a specific command should be used) or not (which is what we
- * currently do, so right now the ioctl value for a given command is the
- * command itself).
- *
- * Hence, we just define the IOCTL_VMCI_foo values directly, with no
- * intermediate IOCTLCMD_ representation.
- */
-# define IOCTLCMD(_cmd) IOCTL_VMCI_ ## _cmd
-#else // if defined(__linux__)
-/*
- * On platforms other than Linux, IOCTLCMD_foo values are just numbers, and
- * we build the IOCTL_VMCI_foo values around these using platform-specific
- * format for encoding arguments and sizes.
- */
-# define IOCTLCMD(_cmd) IOCTLCMD_VMCI_ ## _cmd
-#endif
-
-
-enum IOCTLCmd_VMCI {
- /*
- * We need to bracket the range of values used for ioctls, because x86_64
- * Linux forces us to explicitly register ioctl handlers by value for
- * handling 32 bit ioctl syscalls. Hence FIRST and LAST. Pick something
- * for FIRST that doesn't collide with vmmon (2001+).
- */
-#if defined(__linux__)
- IOCTLCMD(FIRST) = 1951,
-#else
- /* Start at 0. */
- IOCTLCMD(FIRST),
-#endif
- IOCTLCMD(VERSION) = IOCTLCMD(FIRST),
-
- /* BEGIN VMCI */
- IOCTLCMD(INIT_CONTEXT),
- IOCTLCMD(CREATE_PROCESS),
- IOCTLCMD(CREATE_DATAGRAM_PROCESS),
- IOCTLCMD(SHAREDMEM_CREATE),
- IOCTLCMD(SHAREDMEM_ATTACH),
- IOCTLCMD(SHAREDMEM_QUERY),
- IOCTLCMD(SHAREDMEM_DETACH),
- IOCTLCMD(VERSION2),
- IOCTLCMD(QUEUEPAIR_ALLOC),
- IOCTLCMD(QUEUEPAIR_SETPAGEFILE),
- IOCTLCMD(QUEUEPAIR_DETACH),
- IOCTLCMD(DATAGRAM_SEND),
- IOCTLCMD(DATAGRAM_RECEIVE),
- IOCTLCMD(DATAGRAM_REQUEST_MAP),
- IOCTLCMD(DATAGRAM_REMOVE_MAP),
- IOCTLCMD(CTX_ADD_NOTIFICATION),
- IOCTLCMD(CTX_REMOVE_NOTIFICATION),
- IOCTLCMD(CTX_GET_CPT_STATE),
- IOCTLCMD(CTX_SET_CPT_STATE),
- IOCTLCMD(GET_CONTEXT_ID),
- /* END VMCI */
-
- /*
- * BEGIN VMCI SOCKETS
- *
- * We mark the end of the vmci commands and the start of the vmci sockets
- * commands since they are used in separate modules on Linux.
- * */
- IOCTLCMD(LAST),
- IOCTLCMD(SOCKETS_FIRST) = IOCTLCMD(LAST),
- IOCTLCMD(SOCKETS_ACCEPT) = IOCTLCMD(SOCKETS_FIRST),
- IOCTLCMD(SOCKETS_BIND),
- IOCTLCMD(SOCKETS_CLOSE),
- IOCTLCMD(SOCKETS_CONNECT),
- /*
- * The next two values are public (vmci_sockets.h) and cannot be changed.
- * That means the number of values above these cannot be changed either
- * unless the base index (specified below) is updated accordingly.
- */
- IOCTLCMD(SOCKETS_GET_AF_VALUE),
- IOCTLCMD(SOCKETS_GET_LOCAL_CID),
- IOCTLCMD(SOCKETS_GET_SOCK_NAME),
- IOCTLCMD(SOCKETS_GET_SOCK_OPT),
- IOCTLCMD(SOCKETS_GET_VM_BY_NAME),
- IOCTLCMD(SOCKETS_IOCTL),
- IOCTLCMD(SOCKETS_LISTEN),
- IOCTLCMD(SOCKETS_RECV),
- IOCTLCMD(SOCKETS_RECV_FROM),
- IOCTLCMD(SOCKETS_SELECT),
- IOCTLCMD(SOCKETS_SEND),
- IOCTLCMD(SOCKETS_SEND_TO),
- IOCTLCMD(SOCKETS_SET_SOCK_OPT),
- IOCTLCMD(SOCKETS_SHUTDOWN),
- IOCTLCMD(SOCKETS_SOCKET), /* 1990 on Linux. */
- /* END VMCI SOCKETS */
-
- /*
- * We reserve a range of 4 ioctls for VMCI Sockets to grow. We cannot
- * reserve many ioctls here since we are close to overlapping with vmmon
- * ioctls. Define a meta-ioctl if running out of this binary space.
- */
- // Must be last.
- IOCTLCMD(SOCKETS_LAST) = IOCTLCMD(SOCKETS_SOCKET) + 4, /* 1994 on Linux. */
-
- /*
- * The VSockets ioctls occupy the block above. We define a new range of
- * VMCI ioctls to maintain binary compatibility between the user land and
- * the kernel driver. Careful, vmmon ioctls start from 2001, so this means
- * we can add only 4 new VMCI ioctls. Define a meta-ioctl if running out of
- * this binary space.
- */
-
- IOCTLCMD(FIRST2),
- IOCTLCMD(SET_NOTIFY) = IOCTLCMD(FIRST2), /* 1995 on Linux. */
- IOCTLCMD(VMCID_RPC),
- IOCTLCMD(LAST2),
-};
-
-
-#if defined _WIN32
-/*
- * Windows VMCI ioctl definitions.
- */
-
-/*
- * The first is the device name in user-mode. The next two are for registering
- * or opening the device in kernel-mode, and are always in UNICODE.
- */
-#define VMCI_DEVICE_NAME TEXT("\\\\.\\VMCI")
-#define VMCI_DEVICE_NAME_PATH L"\\Device\\vmci"
-#define VMCI_DEVICE_LINK_PATH L"\\DosDevices\\vmci"
-
-/* These values cannot be changed since some of the ioctl values are public. */
-#define FILE_DEVICE_VMCI 0x8103
-#define VMCI_IOCTL_BASE_INDEX 0x801
-#define VMCIIOCTL_BUFFERED(name) \
- CTL_CODE(FILE_DEVICE_VMCI, \
- VMCI_IOCTL_BASE_INDEX + IOCTLCMD_VMCI_ ## name, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-#define VMCIIOCTL_NEITHER(name) \
- CTL_CODE(FILE_DEVICE_VMCI, \
- VMCI_IOCTL_BASE_INDEX + IOCTLCMD_VMCI_ ## name, \
- METHOD_NEITHER, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_VMCI_VERSION VMCIIOCTL_BUFFERED(VERSION)
-
-/* BEGIN VMCI */
-#define IOCTL_VMCI_INIT_CONTEXT VMCIIOCTL_BUFFERED(INIT_CONTEXT)
-#define IOCTL_VMCI_CREATE_PROCESS VMCIIOCTL_BUFFERED(CREATE_PROCESS)
-#define IOCTL_VMCI_CREATE_DATAGRAM_PROCESS \
- VMCIIOCTL_BUFFERED(CREATE_DATAGRAM_PROCESS)
-#define IOCTL_VMCI_HYPERCALL VMCIIOCTL_BUFFERED(HYPERCALL)
-#define IOCTL_VMCI_SHAREDMEM_CREATE \
- VMCIIOCTL_BUFFERED(SHAREDMEM_CREATE)
-#define IOCTL_VMCI_SHAREDMEM_ATTACH \
- VMCIIOCTL_BUFFERED(SHAREDMEM_ATTACH)
-#define IOCTL_VMCI_SHAREDMEM_QUERY \
- VMCIIOCTL_BUFFERED(SHAREDMEM_QUERY)
-#define IOCTL_VMCI_SHAREDMEM_DETACH \
- VMCIIOCTL_BUFFERED(SHAREDMEM_DETACH)
-#define IOCTL_VMCI_VERSION2 VMCIIOCTL_BUFFERED(VERSION2)
-#define IOCTL_VMCI_QUEUEPAIR_ALLOC \
- VMCIIOCTL_BUFFERED(QUEUEPAIR_ALLOC)
-#define IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE \
- VMCIIOCTL_BUFFERED(QUEUEPAIR_SETPAGEFILE)
-#define IOCTL_VMCI_QUEUEPAIR_DETACH \
- VMCIIOCTL_BUFFERED(QUEUEPAIR_DETACH)
-#define IOCTL_VMCI_DATAGRAM_SEND VMCIIOCTL_BUFFERED(DATAGRAM_SEND)
-#define IOCTL_VMCI_DATAGRAM_RECEIVE VMCIIOCTL_NEITHER(DATAGRAM_RECEIVE)
-#define IOCTL_VMCI_DATAGRAM_REQUEST_MAP VMCIIOCTL_BUFFERED(DATAGRAM_REQUEST_MAP)
-#define IOCTL_VMCI_DATAGRAM_REMOVE_MAP VMCIIOCTL_BUFFERED(DATAGRAM_REMOVE_MAP)
-#define IOCTL_VMCI_CTX_ADD_NOTIFICATION VMCIIOCTL_BUFFERED(CTX_ADD_NOTIFICATION)
-#define IOCTL_VMCI_CTX_REMOVE_NOTIFICATION \
- VMCIIOCTL_BUFFERED(CTX_REMOVE_NOTIFICATION)
-#define IOCTL_VMCI_CTX_GET_CPT_STATE \
- VMCIIOCTL_BUFFERED(CTX_GET_CPT_STATE)
-#define IOCTL_VMCI_CTX_SET_CPT_STATE \
- VMCIIOCTL_BUFFERED(CTX_SET_CPT_STATE)
-#define IOCTL_VMCI_GET_CONTEXT_ID \
- VMCIIOCTL_BUFFERED(GET_CONTEXT_ID)
-/* END VMCI */
-
-/* BEGIN VMCI SOCKETS */
-#define IOCTL_VMCI_SOCKETS_ACCEPT \
- VMCIIOCTL_BUFFERED(SOCKETS_ACCEPT)
-#define IOCTL_VMCI_SOCKETS_BIND \
- VMCIIOCTL_BUFFERED(SOCKETS_BIND)
-#define IOCTL_VMCI_SOCKETS_CLOSE \
- VMCIIOCTL_BUFFERED(SOCKETS_CLOSE)
-#define IOCTL_VMCI_SOCKETS_CONNECT \
- VMCIIOCTL_BUFFERED(SOCKETS_CONNECT)
-#define IOCTL_VMCI_SOCKETS_GET_AF_VALUE \
- VMCIIOCTL_BUFFERED(SOCKETS_GET_AF_VALUE)
-#define IOCTL_VMCI_SOCKETS_GET_LOCAL_CID \
- VMCIIOCTL_BUFFERED(SOCKETS_GET_LOCAL_CID)
-#define IOCTL_VMCI_SOCKETS_GET_SOCK_NAME \
- VMCIIOCTL_BUFFERED(SOCKETS_GET_SOCK_NAME)
-#define IOCTL_VMCI_SOCKETS_GET_SOCK_OPT \
- VMCIIOCTL_BUFFERED(SOCKETS_GET_SOCK_OPT)
-#define IOCTL_VMCI_SOCKETS_GET_VM_BY_NAME \
- VMCIIOCTL_BUFFERED(SOCKETS_GET_VM_BY_NAME)
-#define IOCTL_VMCI_SOCKETS_IOCTL \
- VMCIIOCTL_BUFFERED(SOCKETS_IOCTL)
-#define IOCTL_VMCI_SOCKETS_LISTEN \
- VMCIIOCTL_BUFFERED(SOCKETS_LISTEN)
-#define IOCTL_VMCI_SOCKETS_RECV \
- VMCIIOCTL_BUFFERED(SOCKETS_RECV)
-#define IOCTL_VMCI_SOCKETS_RECV_FROM \
- VMCIIOCTL_BUFFERED(SOCKETS_RECV_FROM)
-#define IOCTL_VMCI_SOCKETS_SELECT \
- VMCIIOCTL_BUFFERED(SOCKETS_SELECT)
-#define IOCTL_VMCI_SOCKETS_SEND \
- VMCIIOCTL_BUFFERED(SOCKETS_SEND)
-#define IOCTL_VMCI_SOCKETS_SEND_TO \
- VMCIIOCTL_BUFFERED(SOCKETS_SEND_TO)
-#define IOCTL_VMCI_SOCKETS_SET_SOCK_OPT \
- VMCIIOCTL_BUFFERED(SOCKETS_SET_SOCK_OPT)
-#define IOCTL_VMCI_SOCKETS_SHUTDOWN \
- VMCIIOCTL_BUFFERED(SOCKETS_SHUTDOWN)
-#define IOCTL_VMCI_SOCKETS_SOCKET \
- VMCIIOCTL_BUFFERED(SOCKETS_SOCKET)
-/* END VMCI SOCKETS */
-
-/* BEGIN VMCI USER SPACE DAEMON */
-#define IOCTL_VMCI_VMCID_RPC \
- VMCIIOCTL_BUFFERED(VMCID_RPC)
-/* END VMCI USER SPACE DAEMON */
-
-#endif // _WIN32
-
-
-/*
- * VMCI driver initialization. This block can also be used to
- * pass initial group membership etc.
- */
-typedef struct VMCIInitBlock {
- VMCIId cid;
- VMCIPrivilegeFlags flags;
-#ifdef _WIN32
- uint64 event; /* Handle for signalling vmci calls on windows. */
-#endif // _WIN32
-} VMCIInitBlock;
-
-typedef struct VMCISharedMemInfo {
- VMCIHandle handle;
- uint32 size;
- uint32 result;
- VA64 va; /* Currently only used in the guest. */
- char pageFileName[VMCI_PATH_MAX];
-} VMCISharedMemInfo;
-
-typedef struct VMCIQueuePairAllocInfo {
- VMCIHandle handle;
- VMCIId peer;
- uint32 flags;
- uint64 produceSize;
- uint64 consumeSize;
- VA64 producePageFile; /* User VA. */
- VA64 consumePageFile; /* User VA. */
- uint64 producePageFileSize; /* Size of the file name array. */
- uint64 consumePageFileSize; /* Size of the file name array. */
- int32 result;
- uint32 _pad;
-} VMCIQueuePairAllocInfo;
-
-typedef struct VMCIQueuePairPageFileInfo {
- VMCIHandle handle;
- VA64 producePageFile; /* User VA. */
- VA64 consumePageFile; /* User VA. */
- uint64 producePageFileSize; /* Size of the file name array. */
- uint64 consumePageFileSize; /* Size of the file name array. */
- int32 result;
- uint32 _pad;
-} VMCIQueuePairPageFileInfo;
-
-typedef struct VMCIQueuePairDetachInfo {
- VMCIHandle handle;
- int32 result;
- uint32 _pad;
-} VMCIQueuePairDetachInfo;
-
-typedef struct VMCIDatagramSendRecvInfo {
- VA64 addr;
- uint32 len;
- int32 result;
-} VMCIDatagramSendRecvInfo;
-
-/* Used to create datagram endpoints in guest or host userlevel. */
-typedef struct VMCIDatagramCreateInfo {
- VMCIId resourceID;
- uint32 flags;
- int eventHnd;
- int result; // result of handle create operation
- VMCIHandle handle; // handle if successfull
-} VMCIDatagramCreateInfo;
-
-/* Used to add/remove well-known datagram mappings. */
-typedef struct VMCIDatagramMapInfo {
- VMCIId wellKnownID;
- int result;
-} VMCIDatagramMapInfo;
-
-
-/* Used to add/remove remote context notifications. */
-typedef struct VMCINotifyAddRemoveInfo {
- VMCIId remoteCID;
- int result;
-} VMCINotifyAddRemoveInfo;
-
-
-/* Used to set/get current context's checkpoint state. */
-typedef struct VMCICptBufInfo {
- VA64 cptBuf;
- uint32 cptType;
- uint32 bufSize;
- int32 result;
- uint32 _pad;
-} VMCICptBufInfo;
-
-/* Used to pass notify flag's address to the host driver. */
-typedef struct VMCISetNotifyInfo {
- VA64 notifyUVA;
- int32 result;
- uint32 _pad;
-} VMCISetNotifyInfo;
-
-/* User space daemon command numbers. */
-typedef enum VMCIDRequestType {
- VMCID_REQ_NEW_PAGE_STORE,
- VMCID_REQ_FREE_PAGE_STORE,
- VMCID_REQ_ATTACH_PAGE_STORE,
- VMCID_REQ_DETACH_PAGE_STORE,
-} VMCIDRequestType;
-
-#define VMCI_VMCID_INVALID_REQ CONST64U(-1)
-
-/* Used to pass requests/responses to the user space daemon. */
-typedef struct VMCIDRpc {
- uint64 reqId;
- uint32 reqType;
- uint32 reqResult;
- /* Passing page file names */
- VA64 producePageFile; /* User VA. */
- VA64 consumePageFile; /* User VA. */
- uint64 producePageFileSize; /* Size of the file name array. */
- uint64 consumePageFileSize; /* Size of the file name array. */
- /* Used for attach/detach */
- VA64 produceVA;
- VA64 consumeVA;
- uint64 numProducePages;
- uint64 numConsumePages;
-} VMCIDRpc;
-
-#ifdef __APPLE__
-/*
- * Mac OS ioctl definitions.
- *
- * Mac OS defines _IO* macros, and the core kernel code uses the size encoded
- * in the ioctl value to copy the memory back and forth (depending on the
- * direction encoded in the ioctl value) between the user and kernel address
- * spaces.
- * See iocontrolsMacOS.h for details on how this is done. We use sockets only
- * for vmci.
- */
-
-#include <sys/ioccom.h>
-
-enum VMCrossTalkSockOpt {
- VMCI_SO_VERSION = 0,
- VMCI_SO_CONTEXT = IOCTL_VMCI_INIT_CONTEXT,
- VMCI_SO_PROCESS = IOCTL_VMCI_CREATE_PROCESS,
- VMCI_SO_DATAGRAM_PROCESS = IOCTL_VMCI_CREATE_DATAGRAM_PROCESS,
- VMCI_SO_SHAREDMEM_CREATE = IOCTL_VMCI_SHAREDMEM_CREATE,
- VMCI_SO_SHAREDMEM_ATTACH = IOCTL_VMCI_SHAREDMEM_ATTACH,
- VMCI_SO_SHAREDMEM_QUERY = IOCTL_VMCI_SHAREDMEM_QUERY,
- VMCI_SO_SHAREDMEM_DETACH = IOCTL_VMCI_SHAREDMEM_DETACH,
- VMCI_SO_VERSION2 = IOCTL_VMCI_VERSION2,
- VMCI_SO_QUEUEPAIR_ALLOC = IOCTL_VMCI_QUEUEPAIR_ALLOC,
- VMCI_SO_QUEUEPAIR_SETPAGEFILE = IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE,
- VMCI_SO_QUEUEPAIR_DETACH = IOCTL_VMCI_QUEUEPAIR_DETACH,
- VMCI_SO_DATAGRAM_SEND = IOCTL_VMCI_DATAGRAM_SEND,
- VMCI_SO_DATAGRAM_RECEIVE = IOCTL_VMCI_DATAGRAM_RECEIVE,
- VMCI_SO_DATAGRAM_REQUEST_MAP = IOCTL_VMCI_DATAGRAM_REQUEST_MAP,
- VMCI_SO_DATAGRAM_REMOVE_MAP = IOCTL_VMCI_DATAGRAM_REMOVE_MAP,
- VMCI_SO_CTX_ADD_NOTIFICATION = IOCTL_VMCI_CTX_ADD_NOTIFICATION,
- VMCI_SO_CTX_REMOVE_NOTIFICATION = IOCTL_VMCI_CTX_REMOVE_NOTIFICATION,
- VMCI_SO_CTX_GET_CPT_STATE = IOCTL_VMCI_CTX_GET_CPT_STATE,
- VMCI_SO_CTX_SET_CPT_STATE = IOCTL_VMCI_CTX_SET_CPT_STATE,
- VMCI_SO_GET_CONTEXT_ID = IOCTL_VMCI_GET_CONTEXT_ID,
- VMCI_SO_USERFD,
-};
-
-# define VMCI_MACOS_HOST_DEVICE_BASE "com.vmware.kext.vmci"
-# ifdef VMX86_DEVEL
-# define VMCI_MACOS_HOST_DEVICE VMCI_MACOS_HOST_DEVICE_BASE ".devel"
-# else
-# define VMCI_MACOS_HOST_DEVICE VMCI_MACOS_HOST_DEVICE_BASE
-# endif
-
-#endif
-
-/* Clean up helper macros */
-#undef IOCTLCMD
-
-#endif // ifndef _VMCI_IOCONTROLS_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef _PUBLIC_VMCI_QUEUE_PAIR_H_
-#define _PUBLIC_VMCI_QUEUE_PAIR_H_
-
-/*
- *
- * vmci_queue_pair.h --
- *
- * Defines queue layout in memory, and helper functions to enqueue and
- * dequeue items. XXX needs checksumming?
- */
-
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMX
-#include "includeCheck.h"
-
-#if defined(__APPLE__) && defined(KERNEL)
-# include "vmci_kernel_if.h"
-#endif // __APPLE__
-
-#include "vm_basic_defs.h"
-#include "vm_basic_types.h"
-#include "vm_atomic.h"
-#include "vmci_defs.h"
-#include "vm_assert.h"
-#if defined(SOLARIS)
-#include <sys/uio.h>
-#endif
-
-#if (defined(__linux__) && defined(__KERNEL__)) || defined(SOLARIS)
-#include "vmci_kernel_if.h"
-#endif
-
-
-#if defined(__linux__) && defined(__KERNEL__)
-struct page;
-#endif
-
-
-/*
- * For a queue of buffer 'size' bytes, the tail and head pointers will be in
- * the range [0, size-1].
- */
-
-typedef struct VMCIQueueHeader {
- /* All fields are 64bit and aligned. */
- VMCIHandle handle; /* Identifier. */
- Atomic_uint64 producerTail; /* Offset in this queue. */
- Atomic_uint64 consumerHead; /* Offset in peer queue. */
-} VMCIQueueHeader;
-
-
-/*
- * If one client of a QueuePair is a 32bit entity, we restrict the QueuePair
- * size to be less than 4GB, and use 32bit atomic operations on the head and
- * tail pointers. 64bit atomic read on a 32bit entity involves cmpxchg8b which
- * is an atomic read-modify-write. This will cause traces to fire when a 32bit
- * consumer tries to read the producer's tail pointer, for example, because the
- * consumer has read-only access to the producer's tail pointer.
- *
- * We provide the following macros to invoke 32bit or 64bit atomic operations
- * based on the architecture the code is being compiled on.
- */
-
-/* Architecture independent maximum queue size. */
-#define QP_MAX_QUEUE_SIZE_ARCH_ANY CONST64U(0xffffffff)
-
-#ifdef __x86_64__
-# define QP_MAX_QUEUE_SIZE_ARCH CONST64U(0xffffffffffffffff)
-# define QPAtomic_ReadOffset(x) Atomic_Read64(x)
-# define QPAtomic_WriteOffset(x, y) Atomic_Write64(x, y)
-#else
- /*
- * Wrappers below are being used to call Atomic_Read32 because of the
- * 'type punned' compilation warning received when Atomic_Read32 is
- * called with a Atomic_uint64 pointer typecasted to Atomic_uint32
- * pointer from QPAtomic_ReadOffset. Ditto with QPAtomic_WriteOffset.
- */
-
- static INLINE uint32
- TypeSafe_Atomic_Read32(void *var) // IN:
- {
- return Atomic_Read32((Atomic_uint32 *)(var));
- }
-
- static INLINE void
- TypeSafe_Atomic_Write32(void *var, uint32 val) // IN:
- {
- Atomic_Write32((Atomic_uint32 *)(var), (uint32)(val));
- }
-
-# define QP_MAX_QUEUE_SIZE_ARCH CONST64U(0xffffffff)
-# define QPAtomic_ReadOffset(x) TypeSafe_Atomic_Read32((void *)(x))
-# define QPAtomic_WriteOffset(x, y) \
- TypeSafe_Atomic_Write32((void *)(x), (uint32)(y))
-#endif /* __x86_64__ */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * AddPointer --
- *
- * Helper to add a given offset to a head or tail pointer. Wraps the value
- * of the pointer around the max size of the queue.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-AddPointer(Atomic_uint64 *var, // IN:
- size_t add, // IN:
- uint64 size) // IN:
-{
- uint64 newVal = QPAtomic_ReadOffset(var);
-
- if (newVal >= size - add) {
- newVal -= size;
- }
- newVal += add;
-
- QPAtomic_WriteOffset(var, newVal);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue
- *
- * This data type contains the information about a queue.
- *
- * There are two queues (hence, queue pairs) per transaction model
- * between a pair of end points, A & B. One queue is used by end
- * point A to transmit commands and responses to B. The other queue
- * is used by B to transmit commands and responses.
- *
- * There are six distinct definitions of the VMCIQueue structure.
- * Five are found below along with descriptions of under what build
- * type the VMCIQueue structure type is compiled. The sixth is
- * located in a separate file and is used in the VMKernel context.
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined(VMX86_TOOLS) || defined(VMX86_VMX)
-# if defined(__linux__) && defined(__KERNEL__)
- /*
- * Linux Kernel Guest.
- *
- * The VMCIQueue is two or more machine pages where the first
- * contains the queue header and the second and subsequent pages
- * contain an array of struct page pointers to the actual pages
- * that contain the queue data.
- */
- typedef struct VMCIQueue {
- VMCIQueueHeader queueHeader;
- uint8 _padding[PAGE_SIZE - sizeof(VMCIQueueHeader)];
- struct page *page[0];
- } VMCIQueue;
-# elif defined(SOLARIS)
- /*
- * Solaris Kernel Guest.
- *
- * kmem_cache_alloc with object size of one page is being used to get
- * page aligned memory for queueHeader. VMCIQueue stores a pointer to
- * the queueHeader and the array of virtual addresses of actual pages
- * that contain the queue data.
- */
- typedef struct VMCIQueue {
- VMCIQueueHeader *queueHeaderPtr;
- void *vaddr[0];
- } VMCIQueue;
-
-# else
- /*
- * VMX App and Windows Kernel Guest
- *
- * The VMCIQueue is two or more machine pages where the first
- * contains the queue header and the second and subsequent pages
- * contain the actual queue buffer data.
- */
- typedef struct VMCIQueue {
- VMCIQueueHeader queueHeader;
- uint8 _padding[PAGE_SIZE - sizeof(VMCIQueueHeader)];
- uint8 buffer[0]; // VMX doesn't use this today
- } VMCIQueue;
-# endif
-#else
-# if defined(__linux__) && defined(__KERNEL__)
- /*
- * Linux Kernel Host
- *
- * The VMCIQueueHeader has been created elsewhere and this
- * structure (VMCIQueue) needs a pointer to that
- * VMCIQueueHeader.
- *
- * Also, the queue contents are managed by an array of struct
- * pages which are managed elsewhere. So, this structure simply
- * contains the address of that array of struct pages.
- */
- typedef struct VMCIQueue {
- VMCIQueueHeader *queueHeaderPtr;
- struct page **page;
- } VMCIQueue;
-# else
- /*
- * Windows Host
- *
- * The VMCIQueueHeader has been created elsewhere and this
- * structure (VMCIQueue) needs a pointer to that
- * VMCIQueueHeader.
- *
- * Also, the queue contents are managed by an array of bytes
- * which are managed elsewhere. So, this structure simply
- * contains the address of that array of bytes.
- */
- typedef struct VMCIQueue {
- VMCIQueueHeader *queueHeaderPtr;
- uint8 *buffer;
- } VMCIQueue;
-# endif
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_GetHeader() --
- *
- * Helper routine to get the address of the VMCIQueueHeader.
- * Note that this routine is useful because there are two ways
- * queues are declared (at least as far as the queue header is
- * concerned, anyway). In one way, the queue contains the header
- * in the other the queue contains a pointer to the header. This
- * helper hides that ambiguity from users of queues who need
- * access to the header.
- *
- * Results:
- * The address of the queue header.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE VMCIQueueHeader *
-VMCIQueue_GetHeader(const VMCIQueue *q)
-{
-#if defined(VMX86_TOOLS) || defined(VMX86_VMX)
- /*
- * All guest variants except Solaris have a complete queue header
- */
-#if defined (SOLARIS)
- return (VMCIQueueHeader *)q->queueHeaderPtr;
-#else
- return (VMCIQueueHeader *)&q->queueHeader;
-#endif /* SOLARIS */
-#else
- /*
- * All host variants have a pointer to the queue header
- */
- return (VMCIQueueHeader *)q->queueHeaderPtr;
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_ProducerTail() --
- *
- * Helper routine to get the Producer Tail from the supplied queue.
- *
- * Results:
- * The contents of the queue's producer tail.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-VMCIQueue_ProducerTail(const VMCIQueue *queue)
-{
- return QPAtomic_ReadOffset(&VMCIQueue_GetHeader(queue)->producerTail);
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_ConsumerHead() --
- *
- * Helper routine to get the Consumer Head from the supplied queue.
- *
- * Results:
- * The contents of the queue's consumer tail.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint64
-VMCIQueue_ConsumerHead(const VMCIQueue *queue)
-{
- return QPAtomic_ReadOffset(&VMCIQueue_GetHeader(queue)->consumerHead);
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_AddProducerTail() --
- *
- * Helper routine to increment the Producer Tail. Fundamentally,
- * AddPointer() is used to manipulate the tail itself.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-VMCIQueue_AddProducerTail(VMCIQueue *queue,
- size_t add,
- uint64 queueSize)
-{
- AddPointer(&VMCIQueue_GetHeader(queue)->producerTail, add, queueSize);
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_AddConsumerHead() --
- *
- * Helper routine to increment the Consumer Head. Fundamentally,
- * AddPointer() is used to manipulate the head itself.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-VMCIQueue_AddConsumerHead(VMCIQueue *queue,
- size_t add,
- uint64 queueSize)
-{
- AddPointer(&VMCIQueue_GetHeader(queue)->consumerHead, add, queueSize);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIMemcpy{To,From}QueueFunc() prototypes. Functions of these
- * types are passed around to enqueue and dequeue routines. Note that
- * often the functions passed are simply wrappers around memcpy
- * itself.
- *
- *-----------------------------------------------------------------------------
- */
-typedef int VMCIMemcpyToQueueFunc(VMCIQueue *queue, uint64 queueOffset,
- const void *src, size_t srcOffset,
- size_t size);
-typedef int VMCIMemcpyFromQueueFunc(void *dest, size_t destOffset,
- const VMCIQueue *queue, uint64 queueOffset,
- size_t size);
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIMemcpy{To,From}Queue[v]() prototypes (and, in some cases, an
- * inline version).
- *
- *-----------------------------------------------------------------------------
- */
-
-#if defined (SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
-int VMCIMemcpyToQueue(VMCIQueue *queue, uint64 queueOffset, const void *src,
- size_t srcOffset, size_t size);
-int VMCIMemcpyFromQueue(void *dest, size_t destOffset, const VMCIQueue *queue,
- uint64 queueOffset, size_t size);
-int VMCIMemcpyToQueueV(VMCIQueue *queue, uint64 queueOffset, const void *src,
- size_t srcOffset, size_t size);
-int VMCIMemcpyFromQueueV(void *dest, size_t destOffset, const VMCIQueue *queue,
- uint64 queueOffset, size_t size);
-#elif defined(_WIN32) && defined(WINNT_DDK)
-int VMCIMemcpyToQueue(VMCIQueue *queue, uint64 queueOffset, const void *src,
- size_t srcOffset, size_t size);
-int VMCIMemcpyFromQueue(void *dest, size_t destOffset, const VMCIQueue *queue,
- uint64 queueOffset, size_t size);
-#else
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIMemcpyToQueue --
- *
- * Wrapper for memcpy --- copies from a given buffer to a VMCI Queue.
- * Assumes that offset + size does not wrap around in the queue.
- *
- * Results:
- * Zero on success, negative error code on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE int
-VMCIMemcpyToQueue(VMCIQueue *queue, // OUT:
- uint64 queueOffset, // IN:
- const void *src, // IN:
- size_t srcOffset, // IN:
- size_t size) // IN:
-{
- memcpy(queue->buffer + queueOffset, (uint8 *)src + srcOffset, size);
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIMemcpyFromQueue --
- *
- * Wrapper for memcpy --- copies to a given buffer from a VMCI Queue.
- * Assumes that offset + size does not wrap around in the queue.
- *
- * Results:
- * Zero on success, negative error code on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE int
-VMCIMemcpyFromQueue(void *dest, // OUT:
- size_t destOffset, // IN:
- const VMCIQueue *queue, // IN:
- uint64 queueOffset, // IN:
- size_t size) // IN:
-{
- memcpy((uint8 *)dest + destOffset, queue->buffer + queueOffset, size);
- return 0;
-}
-#endif /* __linux__ && __KERNEL__ */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_CheckAlignment --
- *
- * Checks if the given queue is aligned to page boundary. Returns TRUE if
- * the alignment is good.
- *
- * Results:
- * TRUE or FALSE.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-VMCIQueue_CheckAlignment(const VMCIQueue *queue) // IN:
-{
- /*
- * Checks if header of the queue is page aligned.
- */
- return ((uintptr_t)VMCIQueue_GetHeader(queue) & (PAGE_SIZE - 1)) == 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_GetPointers --
- *
- * Helper routine for getting the head and the tail pointer for a queue.
- * Both the VMCIQueues are needed to get both the pointers for one queue.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-VMCIQueue_GetPointers(const VMCIQueue *produceQ,
- const VMCIQueue *consumeQ,
- uint64 *producerTail,
- uint64 *consumerHead)
-{
- *producerTail = VMCIQueue_ProducerTail(produceQ);
- *consumerHead = VMCIQueue_ConsumerHead(consumeQ);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_ResetPointers --
- *
- * Reset the tail pointer (of "this" queue) and the head pointer (of
- * "peer" queue).
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-VMCIQueue_ResetPointers(VMCIQueue *queue) // IN:
-{
- QPAtomic_WriteOffset(&VMCIQueue_GetHeader(queue)->producerTail, CONST64U(0));
- QPAtomic_WriteOffset(&VMCIQueue_GetHeader(queue)->consumerHead, CONST64U(0));
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_Init --
- *
- * Initializes a queue's state (head & tail pointers).
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-VMCIQueue_Init(const VMCIHandle handle, // IN:
- VMCIQueue *queue) // IN:
-{
- ASSERT_NOT_IMPLEMENTED(VMCIQueue_CheckAlignment(queue));
- VMCIQueue_GetHeader(queue)->handle = handle;
- VMCIQueue_ResetPointers(queue);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueueFreeSpaceInt --
- *
- * Finds available free space in a produce queue to enqueue more
- * data or reports an error if queue pair corruption is detected.
- *
- * Results:
- * Free space size in bytes.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE int
-VMCIQueueFreeSpaceInt(const VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 produceQSize, // IN:
- uint64 *freeSpace) // OUT:
-{
- const uint64 tail = VMCIQueue_ProducerTail(produceQueue);
- const uint64 head = VMCIQueue_ConsumerHead(consumeQueue);
-
- ASSERT(freeSpace);
-
- if (tail >= produceQSize || head >= produceQSize) {
- return VMCI_ERROR_INVALID_SIZE;
- }
-
- /*
- * Deduct 1 to avoid tail becoming equal to head which causes ambiguity. If
- * head and tail are equal it means that the queue is empty.
- */
- if (tail >= head) {
- *freeSpace = produceQSize - (tail - head) - 1;
- } else {
- *freeSpace = head - tail - 1;
- }
-
- return VMCI_SUCCESS;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_FreeSpace --
- *
- * Finds available free space in a produce queue to enqueue more data.
- *
- * Results:
- * On success, free space size in bytes (up to MAX_INT64).
- * On failure, appropriate error code.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE int64
-VMCIQueue_FreeSpace(const VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 produceQSize) // IN:
-{
- uint64 freeSpace;
- int retval;
-
- retval = VMCIQueueFreeSpaceInt(produceQueue, consumeQueue, produceQSize,
- &freeSpace);
-
- if (retval != VMCI_SUCCESS) {
- return retval;
- }
-
- return MIN(freeSpace, MAX_INT64);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_BufReady --
- *
- * Finds available data to dequeue from a consume queue.
- *
- * Results:
- * On success, available data size in bytes (up to MAX_INT64).
- * On failure, appropriate error code.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE int64
-VMCIQueue_BufReady(const VMCIQueue *consumeQueue, // IN:
- const VMCIQueue *produceQueue, // IN:
- const uint64 consumeQSize) // IN:
-{
- int retval;
- uint64 freeSpace;
-
- retval = VMCIQueueFreeSpaceInt(consumeQueue, produceQueue,
- consumeQSize, &freeSpace);
- if (retval != VMCI_SUCCESS) {
- return retval;
- } else {
- uint64 available = consumeQSize - freeSpace - 1;
- return MIN(available, MAX_INT64);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * __VMCIQueue_Enqueue --
- *
- * Enqueues a given buffer to the produce queue using the provided
- * function. As many bytes as possible (space available in the queue)
- * are enqueued.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NOSPACE if no space was available to enqueue data.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise, the number of bytes written to the queue is returned.
- *
- * Side effects:
- * Updates the tail pointer of the produce queue.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-__VMCIQueue_Enqueue(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 produceQSize, // IN:
- const void *buf, // IN:
- size_t bufSize, // IN:
- VMCIMemcpyToQueueFunc memcpyToQueue) // IN:
-{
- const int64 freeSpace = VMCIQueue_FreeSpace(produceQueue, consumeQueue,
- produceQSize);
- const uint64 tail = VMCIQueue_ProducerTail(produceQueue);
- size_t written;
-
- if (!freeSpace) {
- return VMCI_ERROR_QUEUEPAIR_NOSPACE;
- }
- if (freeSpace < 0) {
- return (ssize_t)freeSpace;
- }
-
- written = (size_t)(freeSpace > bufSize ? bufSize : freeSpace);
- if (LIKELY(tail + written < produceQSize)) {
- memcpyToQueue(produceQueue, tail, buf, 0, written);
- } else {
- /* Tail pointer wraps around. */
- const size_t tmp = (size_t)(produceQSize - tail);
-
- memcpyToQueue(produceQueue, tail, buf, 0, tmp);
- memcpyToQueue(produceQueue, 0, buf, tmp, written - tmp);
- }
- AddPointer(&VMCIQueue_GetHeader(produceQueue)->producerTail, written, produceQSize);
- return written;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_Enqueue --
- *
- * Enqueues a given buffer to the produce queue. As many bytes as possible
- * (space available in the queue) are enqueued. If bufSize is larger than
- * the maximum value of ssize_t the result is unspecified.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NOSPACE if no space was available to enqueue data.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise, the number of bytes written to the queue is returned.
- *
- * Side effects:
- * Updates the tail pointer of the produce queue.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-VMCIQueue_Enqueue(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 produceQSize, // IN:
- const void *buf, // IN:
- size_t bufSize) // IN:
-{
- return __VMCIQueue_Enqueue(produceQueue, consumeQueue, produceQSize,
- buf, bufSize, VMCIMemcpyToQueue);
-}
-
-
-#if defined (SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_EnqueueV --
- *
- * Enqueues a given iovec to the produce queue. As many bytes as possible
- * (space available in the queue) are enqueued. If bufSize is larger than
- * the maximum value of ssize_t the result is unspecified.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NOSPACE if no space was available to enqueue data.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise, the number of bytes written to the queue is returned.
- *
- * Side effects:
- * Updates the tail pointer of the produce queue.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-VMCIQueue_EnqueueV(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 produceQSize, // IN:
- struct iovec *iov, // IN:
- size_t iovSize) // IN:
-{
- return __VMCIQueue_Enqueue(produceQueue, consumeQueue, produceQSize,
- (void *)iov, iovSize, VMCIMemcpyToQueueV);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * __VMCIQueue_Dequeue --
- *
- * Dequeues data (if available) from the given consume queue. Writes data
- * to the user provided buffer using the provided function.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise the number of bytes dequeued is returned.
- *
- * Side effects:
- * Updates the head pointer of the consume queue.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-__VMCIQueue_Dequeue(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 consumeQSize, // IN:
- void *buf, // IN:
- size_t bufSize, // IN:
- VMCIMemcpyFromQueueFunc memcpyFromQueue, // IN:
- Bool updateConsumer) // IN:
-{
- const int64 bufReady = VMCIQueue_BufReady(consumeQueue, produceQueue,
- consumeQSize);
- const uint64 head = VMCIQueue_ConsumerHead(produceQueue);
- size_t written;
-
- if (!bufReady) {
- return VMCI_ERROR_QUEUEPAIR_NODATA;
- }
- if (bufReady < 0) {
- return (ssize_t)bufReady;
- }
-
- written = (size_t)(bufReady > bufSize ? bufSize : bufReady);
- if (LIKELY(head + written < consumeQSize)) {
- memcpyFromQueue(buf, 0, consumeQueue, head, written);
- } else {
- /* Head pointer wraps around. */
- const size_t tmp = (size_t)(consumeQSize - head);
-
- memcpyFromQueue(buf, 0, consumeQueue, head, tmp);
- memcpyFromQueue(buf, tmp, consumeQueue, 0, written - tmp);
- }
-
- if (updateConsumer) {
- AddPointer(&VMCIQueue_GetHeader(produceQueue)->consumerHead, written,
- consumeQSize);
- }
- return written;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_Dequeue --
- *
- * Dequeues data (if available) from the given consume queue. Writes data
- * to the user provided buffer. If bufSize is larger than the maximum
- * value of ssize_t the result is unspecified.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise the number of bytes dequeued is returned.
- *
- * Side effects:
- * Updates the head pointer of the consume queue.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-VMCIQueue_Dequeue(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 consumeQSize, // IN:
- void *buf, // IN:
- size_t bufSize) // IN:
-{
- return __VMCIQueue_Dequeue(produceQueue, consumeQueue, consumeQSize,
- buf, bufSize, VMCIMemcpyFromQueue, TRUE);
-}
-
-
-#if defined(SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_DequeueV --
- *
- * Dequeues data (if available) from the given consume queue. Writes data
- * to the user provided iovec. If bufSize is larger than the maximum
- * value of ssize_t the result is unspecified.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise the number of bytes dequeued is returned.
- *
- * Side effects:
- * Updates the head pointer of the consume queue.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-VMCIQueue_DequeueV(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 consumeQSize, // IN:
- struct iovec *iov, // IN:
- size_t iovSize) // IN:
-{
- return __VMCIQueue_Dequeue(produceQueue, consumeQueue, consumeQSize,
- (void *)iov, iovSize, VMCIMemcpyFromQueueV, TRUE);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_Peek --
- *
- * Reads data (if available) from the given consume queue. Copies data
- * to the provided user buffer but does not update the consumer counter
- * of the queue.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise the number of bytes copied to user buffer is returned.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-VMCIQueue_Peek(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 consumeQSize, // IN:
- void *buf, // IN:
- size_t bufSize) // IN:
-{
- return __VMCIQueue_Dequeue(produceQueue, consumeQueue, consumeQSize,
- buf, bufSize, VMCIMemcpyFromQueue, FALSE);
-}
-
-
-#if defined(SOLARIS) || (defined(__linux__) && defined(__KERNEL__))
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQueue_PeekV --
- *
- * Reads data (if available) from the given consume queue. Copies data
- * to the provided user iovec but does not update the consumer counter
- * of the queue.
- *
- * Results:
- * VMCI_ERROR_QUEUEPAIR_NODATA if no data was available to dequeue.
- * VMCI_ERROR_INVALID_SIZE, if any queue pointer is outside the queue
- * (as defined by the queue size).
- * Otherwise the number of bytes copied to user iovec is returned.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE ssize_t
-VMCIQueue_PeekV(VMCIQueue *produceQueue, // IN:
- const VMCIQueue *consumeQueue, // IN:
- const uint64 consumeQSize, // IN:
- struct iovec *iov, // IN:
- size_t iovSize) // IN:
-{
- return __VMCIQueue_Dequeue(produceQueue, consumeQueue, consumeQSize,
- (void *)iov, iovSize, VMCIMemcpyFromQueueV, FALSE);
-}
-#endif
-
-#endif /* !_PUBLIC_VMCI_QUEUE_PAIR_H_ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware.h --
- *
- * Standard include file for VMware source code.
- */
-
-#ifndef _VMWARE_H_
-#define _VMWARE_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMMON
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_DISTRIBUTE
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-#include "vm_basic_defs.h"
-#include "vm_assert.h"
-
-/*
- * Global error codes. Currently used internally, but may be exported
- * to customers one day, like VM_E_XXX in vmcontrol_constants.h
- */
-
-typedef enum VMwareStatus {
- VMWARE_STATUS_SUCCESS, /* success */
- VMWARE_STATUS_ERROR, /* generic error */
- VMWARE_STATUS_NOMEM, /* generic memory allocation error */
- VMWARE_STATUS_INSUFFICIENT_RESOURCES, /* internal or system resource limit exceeded */
- VMWARE_STATUS_INVALID_ARGS /* invalid arguments */
-} VMwareStatus;
-
-#define VMWARE_SUCCESS(s) ((s) == VMWARE_STATUS_SUCCESS)
-
-
-#endif // ifndef _VMWARE_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_begin.h --
- *
- * Begin of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(push, 1)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmware_pack_end.h --
- *
- * End of structure packing. See vmware_pack_init.h for details.
- *
- * Note that we do not use the following construct in this include file,
- * because we want to emit the code every time the file is included --hpreg
- *
- * #ifndef foo
- * # define foo
- * ...
- * #endif
- *
- */
-
-
-#include "vmware_pack_init.h"
-
-
-#ifdef _MSC_VER
-# pragma pack(pop)
-#elif __GNUC__
-__attribute__((__packed__))
-#else
-# error Compiler packing...
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef __VMWARE_PACK_INIT_H__
-# define __VMWARE_PACK_INIT_H__
-
-
-/*
- * vmware_pack_init.h --
- *
- * Platform-independent code to make the compiler pack (i.e. have them
- * occupy the smallest possible space) structure definitions. The following
- * constructs are known to work --hpreg
- *
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * ;
- *
- * typedef
- * #include "vmware_pack_begin.h"
- * struct foo {
- * ...
- * }
- * #include "vmware_pack_end.h"
- * foo;
- */
-
-
-#ifdef _MSC_VER
-/*
- * MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is
- * not balanced within 1 included file. That is annoying because our scheme
- * is based on the pairing being balanced between 2 included files.
- *
- * So we disable this warning, but this is safe because the compiler will also
- * emit warning 4161 when there is more pops than pushes within 1 main
- * file --hpreg
- */
-
-# pragma warning(disable:4103)
-#elif __GNUC__
-#else
-# error Compiler packing...
-#endif
-
-
-#endif /* __VMWARE_PACK_INIT_H__ */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-#ifndef _X86CPUID_H_
-#define _X86CPUID_H_
-
-/* http://www.sandpile.org/ia32/cpuid.htm */
-
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMX
-#define INCLUDE_ALLOW_VMMEXT
-#define INCLUDE_ALLOW_VMKERNEL
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMNIXMOD
-#define INCLUDE_ALLOW_DISTRIBUTE
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMCORE
-#define INCLUDE_ALLOW_VMMON
-#include "includeCheck.h"
-
-#include "vm_basic_types.h"
-
-/*
- * The linux kernel's ptrace.h stupidly defines the bare
- * EAX/EBX/ECX/EDX, which wrecks havoc with our preprocessor tricks.
- */
-#undef EAX
-#undef EBX
-#undef ECX
-#undef EDX
-
-typedef struct CPUIDRegs {
- uint32 eax, ebx, ecx, edx;
-} CPUIDRegs;
-
-typedef union CPUIDRegsUnion {
- uint32 array[4];
- CPUIDRegs regs;
-} CPUIDRegsUnion;
-
-/*
- * Results of calling cpuid(eax, ecx) on all host logical CPU.
- */
-#ifdef _MSC_VER
-#pragma warning (disable :4200) // non-std extension: zero-sized array in struct
-#endif
-
-typedef
-#include "vmware_pack_begin.h"
-struct CPUIDReply {
- /*
- * Unique host logical CPU identifier. It does not change across queries, so
- * we use it to correlate the replies of multiple queries.
- */
- uint64 tag; // OUT
-
- CPUIDRegs regs; // OUT
-}
-#include "vmware_pack_end.h"
-CPUIDReply;
-
-typedef
-#include "vmware_pack_begin.h"
-struct CPUIDQuery {
- uint32 eax; // IN
- uint32 ecx; // IN
- uint32 numLogicalCPUs; // IN/OUT
- CPUIDReply logicalCPUs[0]; // OUT
-}
-#include "vmware_pack_end.h"
-CPUIDQuery;
-
-/*
- * CPUID levels the monitor caches and ones that are not cached, but
- * have fields defined below (short name and actual value).
- *
- * The first parameter defines whether the level is masked/tested
- * during power-on/migration. Any level which is marked as FALSE here
- * *must* have all field masks defined as IGNORE in CPUID_FIELD_DATA.
- * A static assert in lib/cpuidcompat/cpuidcompat.c will check this.
- *
- * IMPORTANT: WHEN ADDING A NEW FIELD TO THE CACHED LEVELS, make sure
- * you update vmcore/vmm/cpu/priv.c:Priv_CPUID() and vmcore/vmm64/bt/
- * cpuid_shared.S (and geninfo) to include the new level.
- */
-
-#define CPUID_CACHED_LEVELS \
- CPUIDLEVEL(TRUE, 0, 0) \
- CPUIDLEVEL(TRUE, 1, 1) \
- CPUIDLEVEL(FALSE,400, 0x40000000) \
- CPUIDLEVEL(FALSE,410, 0x40000010) \
- CPUIDLEVEL(FALSE, 80, 0x80000000) \
- CPUIDLEVEL(TRUE, 81, 0x80000001) \
- CPUIDLEVEL(FALSE, 88, 0x80000008) \
- CPUIDLEVEL(TRUE, 8A, 0x8000000A)
-
-#define CPUID_UNCACHED_LEVELS \
- CPUIDLEVEL(FALSE, 4, 4) \
- CPUIDLEVEL(FALSE, 5, 5) \
- CPUIDLEVEL(FALSE, 6, 6) \
- CPUIDLEVEL(FALSE, A, 0xA) \
- CPUIDLEVEL(FALSE, 86, 0x80000006) \
- CPUIDLEVEL(FALSE, 87, 0x80000007) \
-
-#define CPUID_ALL_LEVELS \
- CPUID_CACHED_LEVELS \
- CPUID_UNCACHED_LEVELS
-
-/* Define cached CPUID levels in the form: CPUID_LEVEL_<ShortName> */
-typedef enum {
-#define CPUIDLEVEL(t, s, v) CPUID_LEVEL_##s,
- CPUID_CACHED_LEVELS
-#undef CPUIDLEVEL
- CPUID_NUM_LEVELS
-} CpuidLevels;
-
-/*
- * CPUID result registers
- */
-
-#define CPUID_REGS \
- CPUIDREG(EAX, eax) \
- CPUIDREG(EBX, ebx) \
- CPUIDREG(ECX, ecx) \
- CPUIDREG(EDX, edx)
-
-typedef enum {
-#define CPUIDREG(uc, lc) CPUID_REG_##uc,
- CPUID_REGS
-#undef CPUIDREG
- CPUID_NUM_REGS
-} CpuidRegs;
-
-/*
- * CPU vendors
- */
-
-typedef enum {
- CPUID_VENDOR_UNKNOWN,
- CPUID_VENDOR_COMMON,
- CPUID_VENDOR_INTEL,
- CPUID_VENDOR_AMD,
- CPUID_VENDOR_CYRIX,
- CPUID_VENDOR_VIA,
- CPUID_NUM_VENDORS
-} CpuidVendors;
-
-#define CPUID_INTEL_VENDOR_STRING "GenuntelineI"
-#define CPUID_AMD_VENDOR_STRING "AuthcAMDenti"
-#define CPUID_CYRIX_VENDOR_STRING "CyriteadxIns"
-#define CPUID_VIA_VENDOR_STRING "CentaulsaurH"
-#define CPUID_HYPERV_HYPERVISOR_VENDOR_STRING "Microsoft Hv"
-#define CPUID_INTEL_VENDOR_STRING_FIXED "GenuineIntel"
-#define CPUID_AMD_VENDOR_STRING_FIXED "AuthenticAMD"
-#define CPUID_CYRIX_VENDOR_STRING_FIXED "CyrixInstead"
-#define CPUID_VIA_VENDOR_STRING_FIXED "CentaurHauls"
-
-/*
- * FIELDDEF can be defined to process the CPUID information provided
- * in the following CPUID_FIELD_DATA macro. The first parameter is
- * the CPUID level of the feature (must be defined in CPUID_*_LEVELS.
- * The second parameter is the register the field is contained in
- * (defined in CPUID_REGS). The third field is the vendor this
- * feature applies to. "COMMON" means all vendors apply. UNKNOWN may
- * not be used here. The fourth and fifth parameters are the bit
- * position of the field and the width, respectively. The sixth is
- * the text name of the field.
- *
- * The seventh and eighth parameters specify the default CPUID
- * behavior for power-on, guest view, and migration tests (cpt/rsm &
- * vmotion). The eighth parameter is ignored for types other than
- * MASK & TEST, and must be zero in this case.
- *
- * When adding a new field, be sure to consider its purpose. The
- * following list of types is provided in order of likely use.
- *
- * NOTE: this form of representation is separate from the masking
- * system specified via the config file. That is because this
- * representation must take into account multi-bit fields.
- *
- * HOST - Passthrough host value and cannot change during migration.
- * MASK, 0 - Hide from the guest, because we don't support it or we
- * don't want the guest to know that it exists.
- * IGNORE - Ignore this field for all tests
- *
- * (Think twice before using the below mask types/combinations)
- *
- * MASK, x - Force the guest to always see x, and don't compare for
- * migration -- only APIC as of today; it is controlled by
- * software and we know how to toggle it
- * TEST, x - Require host CPUID field to be x for power-on
- * RSVD - Hidden from the guest, but compared during migration
- *
- *
- * Table to explain mask type meanings:
- *
- * IGNR MASK TEST HOST RSVD
- * --------------------------------------------------------
- * Req'd val for power-on - - x - -
- * Value guest sees * x * * 0
- * Checked on migration? N N Y Y Y
- *
- * * - initial host's power-on CPUID value
- *
- * FIELDDEFA takes a ninth parameter, the name used when creating
- * accessor functions in lib/public/cpuidInfoFuncs.h.
- *
- * FLAGDEF/FLAGDEFA is defined identically to fields, but their
- * accessors are more appropriate for 1-bit flags.
- */
-
-typedef enum {
- CPUID_FIELD_MASK_IGNORE,
- CPUID_FIELD_MASK_MASK,
- CPUID_FIELD_MASK_TEST,
- CPUID_FIELD_MASK_HOST,
- CPUID_FIELD_MASK_RSVD,
- CPUID_NUM_FIELD_MASKS
-} CpuidFieldMasks;
-
-
-typedef enum {
- CPUID_FIELD_SUPPORTED_NO,
- CPUID_FIELD_SUPPORTED_YES,
- CPUID_FIELD_SUPPORTED_ANY,
- CPUID_FIELD_SUPPORTED_NA,
- CPUID_NUM_FIELD_SUPPORTEDS
-} CpuidFieldSupported;
-
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_0 \
-FIELDDEF( 0, EAX, COMMON, 0, 32, NUMLEVELS, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 0, EBX, COMMON, 0, 32, VENDOR1, YES, HOST, 0, TRUE) \
-FIELDDEF( 0, ECX, COMMON, 0, 32, VENDOR3, YES, HOST, 0, TRUE) \
-FIELDDEF( 0, EDX, COMMON, 0, 32, VENDOR2, YES, HOST, 0, TRUE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_1 \
-FIELDDEFA( 1, EAX, COMMON, 0, 4, STEPPING, ANY, IGNORE, 0, FALSE, STEPPING) \
-FIELDDEFA( 1, EAX, COMMON, 4, 4, MODEL, ANY, IGNORE, 0, FALSE, MODEL) \
-FIELDDEFA( 1, EAX, COMMON, 8, 4, FAMILY, YES, HOST, 0, FALSE, FAMILY) \
-FIELDDEF( 1, EAX, COMMON, 12, 2, TYPE, ANY, IGNORE, 0, FALSE) \
-FIELDDEFA( 1, EAX, COMMON, 16, 4, EXTMODEL, ANY, IGNORE, 0, FALSE, EXT_MODEL) \
-FIELDDEFA( 1, EAX, COMMON, 20, 8, EXTFAMILY, YES, HOST, 0, FALSE, EXT_FAMILY) \
-FIELDDEF( 1, EBX, COMMON, 0, 8, BRAND_ID, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 1, EBX, COMMON, 8, 8, CLFL_SIZE, ANY, IGNORE, 0, FALSE) \
-FIELDDEFA( 1, EBX, COMMON, 16, 8, LCPU_COUNT, ANY, IGNORE, 0, FALSE, LCPU_COUNT) \
-FIELDDEFA( 1, EBX, COMMON, 24, 8, APICID, ANY, IGNORE, 0, FALSE, APICID) \
-FLAGDEFA( 1, ECX, COMMON, 0, 1, SSE3, YES, HOST, 0, TRUE, SSE3) \
-FLAGDEF( 1, ECX, INTEL, 2, 1, NDA2, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, COMMON, 3, 1, MWAIT, NO, MASK, 0, FALSE, MWAIT) \
-FLAGDEFA( 1, ECX, INTEL, 4, 1, DSCPL, NO, MASK, 0, FALSE, DSCPL) \
-FLAGDEFA( 1, ECX, INTEL, 5, 1, VMX, NO, MASK, 0, FALSE, VMX) \
-FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 7, 1, EST, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 8, 1, TM2, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, COMMON, 9, 1, SSSE3, YES, HOST, 0, TRUE, SSSE3) \
-FLAGDEF( 1, ECX, INTEL, 10, 1, HTCACHE, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, COMMON, 13, 1, CMPX16, YES, HOST, 0, TRUE, CMPX16) \
-FLAGDEF( 1, ECX, INTEL, 14, 1, xPPR, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 15, 1, PERF_MSR, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 18, 1, DCA, NO, MASK, 0, FALSE) \
-FLAGDEFA( 1, ECX, INTEL, 19, 1, SSE41, YES, HOST, 0, TRUE, SSE41) \
-FLAGDEFA( 1, ECX, INTEL, 20, 1, SSE42, YES, HOST, 0, TRUE, SSE42) \
-FLAGDEF( 1, ECX, INTEL, 21, 1, X2APIC, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 22, 1, MOVBE, NO, RSVD, 0, TRUE) \
-FLAGDEFA( 1, ECX, COMMON, 23, 1, POPCNT, YES, HOST, 0, TRUE, POPCNT) \
-FLAGDEF( 1, ECX, INTEL, 24, 1, ULE, NO, RSVD, 0, TRUE) \
-FLAGDEF( 1, ECX, INTEL, 26, 1, XSAVE, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, ECX, INTEL, 27, 1, OSXSAVE, NO, RSVD, 0, TRUE) \
-FLAGDEFA( 1, ECX, COMMON, 31, 1, HYPERVISOR, ANY, IGNORE, 0, FALSE, HYPERVISOR)\
-FLAGDEFA( 1, EDX, COMMON, 0, 1, FPU, YES, HOST, 0, TRUE, FPU) \
-FLAGDEFA( 1, EDX, COMMON, 1, 1, VME, YES, HOST, 0, FALSE, VME) \
-FLAGDEF( 1, EDX, COMMON, 2, 1, DBGE, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, COMMON, 3, 1, PGSZE, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 4, 1, TSC, YES, HOST, 0, TRUE, TSC) \
-FLAGDEF( 1, EDX, COMMON, 5, 1, MSR, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 6, 1, PAE, YES, HOST, 0, FALSE, PAE) \
-FLAGDEF( 1, EDX, COMMON, 7, 1, MCK, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, COMMON, 8, 1, CPMX, YES, HOST, 0, TRUE) \
-FLAGDEFA( 1, EDX, COMMON, 9, 1, APIC, ANY, MASK, 1, FALSE, APIC) \
-FLAGDEFA( 1, EDX, COMMON, 11, 1, SEP, YES, HOST, 0, TRUE, SEP) \
-FLAGDEFA( 1, EDX, COMMON, 12, 1, MTRR, YES, HOST, 0, FALSE, MTRR) \
-FLAGDEFA( 1, EDX, COMMON, 13, 1, PGE, YES, HOST, 0, FALSE, PGE) \
-FLAGDEFA( 1, EDX, COMMON, 14, 1, MCA, YES, HOST, 0, FALSE, MCA) \
-FLAGDEFA( 1, EDX, COMMON, 15, 1, CMOV, YES, HOST, 0, TRUE, CMOV) \
-FLAGDEFA( 1, EDX, COMMON, 16, 1, PAT, YES, HOST, 0, FALSE, PAT) \
-FLAGDEF( 1, EDX, COMMON, 17, 1, 36PG, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 18, 1, PSN, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 19, 1, CLFL, YES, HOST, 0, TRUE, CLFL) \
-FLAGDEF( 1, EDX, INTEL, 21, 1, DTES, YES, HOST, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 22, 1, ACPI, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 23, 1, MMX, YES, HOST, 0, TRUE, MMX) \
-FLAGDEFA( 1, EDX, COMMON, 24, 1, FXSAVE, YES, HOST, 0, TRUE, FXSAVE) \
-FLAGDEFA( 1, EDX, COMMON, 25, 1, SSE, YES, HOST, 0, TRUE, SSE) \
-FLAGDEFA( 1, EDX, COMMON, 26, 1, SSE2, YES, HOST, 0, TRUE, SSE2) \
-FLAGDEF( 1, EDX, INTEL, 27, 1, SS, YES, HOST, 0, FALSE) \
-FLAGDEFA( 1, EDX, COMMON, 28, 1, HT, NO, MASK, 0, FALSE, HT) \
-FLAGDEF( 1, EDX, INTEL, 29, 1, TM, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 30, 1, IA64, NO, MASK, 0, FALSE) \
-FLAGDEF( 1, EDX, INTEL, 31, 1, PBE, NO, MASK, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_4 \
-FIELDDEF( 4, EAX, INTEL, 0, 5, CACHE_TYPE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EAX, INTEL, 5, 3, CACHE_LEVEL, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EAX, INTEL, 14, 12, CACHE_NUMHT_SHARING, NA, IGNORE, 0, FALSE) \
-FIELDDEFA( 4, EAX, INTEL, 26, 6, CORE_COUNT, NA, IGNORE, 0, FALSE, INTEL_CORE_COUNT) \
-FIELDDEF( 4, EBX, INTEL, 0, 12, CACHE_LINE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EBX, INTEL, 12, 10, CACHE_PART, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 4, EBX, INTEL, 22, 10, CACHE_WAYS, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_5 \
-FIELDDEF( 5, EAX, COMMON, 0, 16, MWAIT_MIN_SIZE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EBX, COMMON, 0, 16, MWAIT_MAX_SIZE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 5, ECX, COMMON, 0, 1, MWAIT_EXTENSIONS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 5, ECX, COMMON, 1, 1, MWAIT_INTR_BREAK, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 0, 4, MWAIT_C0_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 4, 4, MWAIT_C1_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 8, 4, MWAIT_C2_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 12, 4, MWAIT_C3_SUBSTATE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 5, EDX, INTEL, 16, 4, MWAIT_C4_SUBSTATE, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_6 \
-FLAGDEF( 6, EAX, INTEL, 0, 1, THERMAL_SENSOR, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 6, EAX, INTEL, 1, 1, TURBO_MODE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 6, EBX, INTEL, 0, 4, NUM_INTR_THRESHOLDS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 6, ECX, INTEL, 0, 1, HW_COORD_FEEDBACK, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_A \
-FIELDDEFA( A, EAX, INTEL, 0, 8, PMC_VERSION, NA, IGNORE, 0, FALSE, PMC_VERSION) \
-FIELDDEFA( A, EAX, INTEL, 8, 8, NUM_PMCS, NA, IGNORE, 0, FALSE, NUM_PMCS) \
-FIELDDEF( A, EAX, INTEL, 16, 8, PMC_BIT_WIDTH, NA, IGNORE, 0, FALSE) \
-FIELDDEFA( A, EAX, INTEL, 24, 8, PMC_EBX_LENGTH, NA, IGNORE, 0, FALSE, PMC_EBX_LENGTH) \
-FLAGDEF( A, EBX, INTEL, 0, 1, PMC_CORE_CYCLE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 1, 1, PMC_INSTR_RETIRED, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 2, 1, PMC_REF_CYCLES, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 3, 1, PMC_LAST_LVL_CREF, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 4, 1, PMC_LAST_LVL_CMISS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 5, 1, PMC_BR_INST_RETIRED, NA, IGNORE, 0, FALSE) \
-FLAGDEF( A, EBX, INTEL, 6, 1, PMC_BR_MISS_RETIRED, NA, IGNORE, 0, FALSE) \
-FIELDDEF( A, EDX, INTEL, 0, 5, PMC_FIXED_NUM, NA, IGNORE, 0, FALSE) \
-FIELDDEF( A, EDX, INTEL, 5, 8, PMC_FIXED_SIZE, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_80 \
-FIELDDEF( 80, EAX, COMMON, 0, 32, NUM_EXT_LEVELS, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 80, EBX, AMD, 0, 32, AMD_VENDOR1, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 80, ECX, AMD, 0, 32, AMD_VENDOR3, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 80, EDX, AMD, 0, 32, AMD_VENDOR2, NA, IGNORE, 0, FALSE)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_81 \
-FIELDDEF( 81, EAX, INTEL, 0, 32, UNKNOWN81EAX, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 0, 4, STEPPING, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 4, 4, MODEL, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 8, 4, FAMILY, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 12, 2, TYPE, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 16, 4, EXTMODEL, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EAX, AMD, 20, 8, EXTFAMILY, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EBX, INTEL, 0, 32, UNKNOWN81EBX, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EBX, AMD, 0, 16, BRAND_ID, ANY, IGNORE, 0, FALSE) \
-FIELDDEF( 81, EBX, AMD, 16, 16, UNDEF, ANY, IGNORE, 0, FALSE) \
-FLAGDEFA( 81, ECX, COMMON, 0, 1, LAHF, YES, HOST, 0, TRUE, LAHF64) \
-FLAGDEFA( 81, ECX, AMD, 1, 1, CMPLEGACY, NO, MASK, 0, FALSE, CMPLEGACY) \
-FLAGDEFA( 81, ECX, AMD, 2, 1, SVM, NO, MASK, 0, FALSE, SVM) \
-FLAGDEFA( 81, ECX, AMD, 3, 1, EXTAPICSPC, YES, HOST, 0, FALSE, EXTAPICSPC) \
-FLAGDEFA( 81, ECX, AMD, 4, 1, CR8AVAIL, NO, MASK, 0, FALSE, CR8AVAIL) \
-FLAGDEFA( 81, ECX, AMD, 5, 1, ABM, YES, HOST, 0, TRUE, ABM) \
-FLAGDEFA( 81, ECX, AMD, 6, 1, SSE4A, YES, HOST, 0, TRUE, SSE4A) \
-FLAGDEF( 81, ECX, AMD, 7, 1, MISALIGNED_SSE, YES, HOST, 0, TRUE) \
-FLAGDEFA( 81, ECX, AMD, 8, 1, 3DNPREFETCH, YES, HOST, 0, TRUE, 3DNPREFETCH) \
-FLAGDEF( 81, ECX, AMD, 9, 1, OSVW, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, ECX, AMD, 10, 1, IBS, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, ECX, AMD, 11, 1, SSE5, NO, RSVD, 0, TRUE) \
-FLAGDEF( 81, ECX, AMD, 12, 1, SKINIT, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, ECX, AMD, 13, 1, WATCHDOG, NO, MASK, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 0, 1, FPU, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 1, 1, VME, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 2, 1, DBGE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 3, 1, PGSZE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 4, 1, TSC, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 5, 1, MSR, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 6, 1, PAE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 7, 1, MCK, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 8, 1, CPMX, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 9, 1, APIC, ANY, MASK, 1, FALSE) \
-FLAGDEFA( 81, EDX, COMMON, 11, 1, SYSC, ANY, IGNORE, 0, TRUE, SYSC) \
-FLAGDEF( 81, EDX, AMD, 12, 1, MTRR, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 13, 1, PGE, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 14, 1, MCA, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 15, 1, CMOV, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 16, 1, PAT, YES, HOST, 0, FALSE) \
-FLAGDEF( 81, EDX, AMD, 17, 1, 36PG, YES, HOST, 0, FALSE) \
-FLAGDEFA( 81, EDX, COMMON, 20, 1, NX, YES, HOST, 0, FALSE, NX) \
-FLAGDEFA( 81, EDX, AMD, 22, 1, MMXEXT, YES, HOST, 0, TRUE, MMXEXT) \
-FLAGDEF( 81, EDX, AMD, 23, 1, MMX, YES, HOST, 0, TRUE) \
-FLAGDEF( 81, EDX, AMD, 24, 1, FXSAVE, YES, HOST, 0, TRUE) \
-FLAGDEFA( 81, EDX, AMD, 25, 1, FFXSR, YES, HOST, 0, FALSE, FFXSR) \
-FLAGDEF( 81, EDX, AMD, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
-FLAGDEFA( 81, EDX, COMMON, 27, 1, RDTSCP, YES, HOST, 0, TRUE, RDTSCP) \
-FLAGDEFA( 81, EDX, COMMON, 29, 1, LM, YES, TEST, 1, FALSE, LM) \
-FLAGDEFA( 81, EDX, AMD, 30, 1, 3DNOWPLUS, YES, HOST, 0, TRUE, 3DNOWPLUS) \
-FLAGDEFA( 81, EDX, AMD, 31, 1, 3DNOW, YES, HOST, 0, TRUE, 3DNOW)
-
-/* LEVEL, REG, VENDOR, POS, SIZE, NAME, MON SUPP, MASK TYPE, SET TO, CPL3, [FUNC] */
-#define CPUID_FIELD_DATA_LEVEL_8x \
-FIELDDEF( 86, ECX, AMD, 0, 8, L2CACHE_LINE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, ECX, AMD, 8, 4, L2CACHE_LINE_PER_TAG, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, ECX, AMD, 12, 4, L2CACHE_WAYS, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, ECX, AMD, 16, 16, L2CACHE_SIZE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 0, 8, L3CACHE_LINE, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 8, 4, L3CACHE_LINE_PER_TAG,NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 12, 4, L3CACHE_WAYS, NA, IGNORE, 0, FALSE) \
-FIELDDEF( 86, EDX, AMD, 18, 14, L3CACHE_SIZE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 0, 1, TS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 1, 1, FID, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 2, 1, VID, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 3, 1, TTP, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 4, 1, TM, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 5, 1, STC, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 6, 1, 100MHZSTEPS, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, AMD, 7, 1, HWPSTATE, NA, IGNORE, 0, FALSE) \
-FLAGDEF( 87, EDX, COMMON, 8, 1, TSC_INVARIANT, NA, IGNORE, 0, FALSE) \
-FIELDDEFA(88, EAX, COMMON, 0, 8, PHYSBITS, NA, IGNORE, 0, FALSE, PHYS_BITS) \
-FIELDDEFA(88, EAX, COMMON, 8, 8, VIRTBITS, NA, IGNORE, 0, FALSE, VIRT_BITS) \
-FIELDDEFA(88, ECX, AMD, 0, 8, CORE_COUNT, NA, IGNORE, 0, FALSE, AMD_CORE_COUNT) \
-FIELDDEFA(88, ECX, AMD, 12, 4, APICID_COREID_SIZE, NA, IGNORE, 0, FALSE, AMD_APICID_COREID_SIZE) \
-FIELDDEFA(8A, EAX, AMD, 0, 8, SVM_REVISION, NO, MASK, 0, FALSE, SVM_REVISION) \
-FLAGDEF( 8A, EAX, AMD, 8, 1, SVM_HYPERVISOR, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, EAX, AMD, 9, 23, SVMEAX_RSVD, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, EBX, AMD, 0, 32, SVM_N_ASIDS, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, ECX, AMD, 0, 32, SVMECX_RSVD, NO, MASK, 0, FALSE) \
-FLAGDEFA( 8A, EDX, AMD, 0, 1, SVM_NP, NO, MASK, 0, FALSE, NPT) \
-FLAGDEF( 8A, EDX, AMD, 1, 1, SVM_LBR, NO, MASK, 0, FALSE) \
-FLAGDEF( 8A, EDX, AMD, 2, 1, SVM_LOCK, NO, MASK, 0, FALSE) \
-FLAGDEF( 8A, EDX, AMD, 3, 1, SVM_NRIP, NO, MASK, 0, FALSE) \
-FIELDDEF( 8A, EDX, AMD, 4, 28, SVMEDX_RSVD, NO, MASK, 0, FALSE)
-
-#define CPUID_FIELD_DATA \
- CPUID_FIELD_DATA_LEVEL_0 \
- CPUID_FIELD_DATA_LEVEL_1 \
- CPUID_FIELD_DATA_LEVEL_4 \
- CPUID_FIELD_DATA_LEVEL_5 \
- CPUID_FIELD_DATA_LEVEL_6 \
- CPUID_FIELD_DATA_LEVEL_A \
- CPUID_FIELD_DATA_LEVEL_80 \
- CPUID_FIELD_DATA_LEVEL_81 \
- CPUID_FIELD_DATA_LEVEL_8x
-
-/*
- * Define all field and flag values as an enum. The result is a full
- * set of values taken from the table above in the form:
- *
- * CPUID_FEATURE_<vendor>_ID<level><reg>_<name> == mask for feature
- * CPUID_<vendor>_ID<level><reg>_<name>_MASK == mask for field
- * CPUID_<vendor>_ID<level><reg>_<name>_SHIFT == offset of field
- *
- * e.g. - CPUID_FEATURE_COMMON_ID1EDX_FPU = 0x1
- * - CPUID_COMMON_ID88EAX_VIRTBITS_MASK = 0xff00
- * - CPUID_COMMON_ID88EAX_VIRTBITS_SHIFT = 8
- *
- * Note: The FEATURE/MASK definitions must use some gymnastics to get
- * around a warning when shifting left by 32.
- */
-#define VMW_BIT_MASK(shift) (((1 << (shift - 1)) << 1) - 1)
-
-#define FIELDDEF(lvl, reg, vend, bitpos, size, name, s, m, v, c3) \
- CPUID_##vend##_ID##lvl##reg##_##name##_SHIFT = bitpos, \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK = \
- VMW_BIT_MASK(size) << bitpos, \
- CPUID_FEATURE_##vend##_ID##lvl##reg##_##name = \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK,
-
-/* Before simplifying this take a look at bug 293638... */
-#define FIELDDEFA(lvl, reg, vend, bitpos, size, name, s, m, v, c3, f) \
- CPUID_##vend##_ID##lvl##reg##_##name##_SHIFT = bitpos, \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK = \
- VMW_BIT_MASK(size) << bitpos, \
- CPUID_FEATURE_##vend##_ID##lvl##reg##_##name = \
- CPUID_##vend##_ID##lvl##reg##_##name##_MASK,
-
-#define FLAGDEFA FIELDDEFA
-#define FLAGDEF FIELDDEF
-
-enum {
- /* Define data for every CPUID field we have */
- CPUID_FIELD_DATA
-};
-#undef VMW_BIT_MASK
-#undef FIELDDEF
-#undef FLAGDEF
-#undef FIELDDEFA
-#undef FLAGDEFA
-
-/*
- * Legal CPUID config file mask characters. For a description of the
- * cpuid masking system, please see:
- *
- * http://vmweb.vmware.com/~mts/cgi-bin/view.cgi/Apps/CpuMigrationChecks
- */
-
-#define CPUID_MASK_HIDE_CHR '0'
-#define CPUID_MASK_HIDE_STR "0"
-#define CPUID_MASK_FORCE_CHR '1'
-#define CPUID_MASK_FORCE_STR "1"
-#define CPUID_MASK_PASS_CHR '-'
-#define CPUID_MASK_PASS_STR "-"
-#define CPUID_MASK_TRUE_CHR 'T'
-#define CPUID_MASK_TRUE_STR "T"
-#define CPUID_MASK_FALSE_CHR 'F'
-#define CPUID_MASK_FALSE_STR "F"
-#define CPUID_MASK_IGNORE_CHR 'X'
-#define CPUID_MASK_IGNORE_STR "X"
-#define CPUID_MASK_HOST_CHR 'H'
-#define CPUID_MASK_HOST_STR "H"
-#define CPUID_MASK_RSVD_CHR 'R'
-#define CPUID_MASK_RSVD_STR "R"
-#define CPUID_MASK_INSTALL_CHR 'I'
-#define CPUID_MASK_INSTALL_STR "I"
-
-/*
- * If a level is listed as not masked/tested in CPUID_LEVELS above,
- * use all "don't care" values for its mask.
- */
-
-#define CPT_DFLT_UNDEFINED_MASK "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX"
-
-/*
- * When LM is disabled, we overlay the following masks onto the
- * guest's default masks. Any level that is not defined below should
- * be treated as all "-"s
- */
-
-#define CPT_ID1ECX_LM_DISABLED "----:----:----:----:--0-:----:----:----"
-#define CPT_ID81EDX_LM_DISABLED "--0-:----:----:----:----:----:----:----"
-#define CPT_ID81ECX_LM_DISABLED "----:----:----:----:----:----:----:---0"
-
-#define CPT_GET_LM_DISABLED_MASK(lvl, reg) \
- ((lvl == 1 && reg == CPUID_REG_ECX) ? CPT_ID1ECX_LM_DISABLED : \
- (lvl == 0x80000001 && reg == CPUID_REG_ECX) ? CPT_ID81ECX_LM_DISABLED : \
- (lvl == 0x80000001 && reg == CPUID_REG_EDX) ? CPT_ID81EDX_LM_DISABLED : \
- NULL)
-
-/*
- * Macro to define GET and SET functions for various common CPUID
- * fields. To create function for a new field, simply name it (CPUID_
- * and CPUID_SET_ are automatically prepended), and list the field
- * name that it needs to use.
- */
-
-#define FIELD_FUNC(name, field) \
- static INLINE uint32 CPUID_##name(uint32 reg) \
- { \
- return (reg & field##_MASK) >> field##_SHIFT; \
- } \
- static INLINE void CPUID_SET_##name(uint32 *reg, uint32 val) \
- { \
- *reg = (*reg & ~field##_MASK) | (val << field##_SHIFT); \
- }
-
-FIELD_FUNC(STEPPING, CPUID_COMMON_ID1EAX_STEPPING)
-FIELD_FUNC(MODEL, CPUID_COMMON_ID1EAX_MODEL)
-FIELD_FUNC(FAMILY, CPUID_COMMON_ID1EAX_FAMILY)
-FIELD_FUNC(TYPE, CPUID_COMMON_ID1EAX_TYPE)
-FIELD_FUNC(EXTENDED_MODEL, CPUID_COMMON_ID1EAX_EXTMODEL)
-FIELD_FUNC(EXTENDED_FAMILY, CPUID_COMMON_ID1EAX_EXTFAMILY)
-FIELD_FUNC(LCPU_COUNT, CPUID_COMMON_ID1EBX_LCPU_COUNT)
-FIELD_FUNC(APICID, CPUID_COMMON_ID1EBX_APICID)
-FIELD_FUNC(PA_BITS, CPUID_COMMON_ID88EAX_PHYSBITS)
-FIELD_FUNC(VIRT_BITS, CPUID_COMMON_ID88EAX_VIRTBITS)
-FIELD_FUNC(SVM_REVISION, CPUID_AMD_ID8AEAX_SVM_REVISION)
-FIELD_FUNC(SVM_N_ASIDS, CPUID_AMD_ID8AEBX_SVM_N_ASIDS)
-FIELD_FUNC(INTEL_CORE_COUNT, CPUID_INTEL_ID4EAX_CORE_COUNT)
-FIELD_FUNC(AMD_CORE_COUNT, CPUID_AMD_ID88ECX_CORE_COUNT)
-FIELD_FUNC(AMD_APICID_COREID_SIZE, CPUID_AMD_ID88ECX_APICID_COREID_SIZE)
-FIELD_FUNC(AMD_EXTAPICSPC, CPUID_AMD_ID81ECX_EXTAPICSPC)
-FIELD_FUNC(NUM_PMCS, CPUID_INTEL_IDAEAX_NUM_PMCS)
-FIELD_FUNC(MWAIT_MIN_SIZE, CPUID_COMMON_ID5EAX_MWAIT_MIN_SIZE)
-FIELD_FUNC(MWAIT_MAX_SIZE, CPUID_COMMON_ID5EBX_MWAIT_MAX_SIZE)
-FIELD_FUNC(MWAIT_C0_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C0_SUBSTATE)
-FIELD_FUNC(MWAIT_C1_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C1_SUBSTATE)
-FIELD_FUNC(MWAIT_C2_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C2_SUBSTATE)
-FIELD_FUNC(MWAIT_C3_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C3_SUBSTATE)
-FIELD_FUNC(MWAIT_C4_SUBSTATE, CPUID_INTEL_ID5EDX_MWAIT_C4_SUBSTATE)
-#undef FIELD_FUNC
-
-
-/*
- * Definitions of various fields' values and more complicated
- * macros/functions for reading cpuid fields.
- */
-
-/* Effective Intel CPU Families */
-#define CPUID_FAMILY_486 4
-#define CPUID_FAMILY_P5 5
-#define CPUID_FAMILY_P6 6
-#define CPUID_FAMILY_P4 15
-
-/* Effective AMD CPU Families */
-#define CPUID_FAMILY_5x86 4
-#define CPUID_FAMILY_K5 5
-#define CPUID_FAMILY_K6 5
-#define CPUID_FAMILY_K7 6
-#define CPUID_FAMILY_K8 15
-#define CPUID_FAMILY_K8L 16
-#define CPUID_FAMILY_K8MOBILE 17
-#define CPUID_FAMILY_EXTENDED 15
-
-/* Intel model information */
-#define CPUID_MODEL_PPRO 1
-#define CPUID_MODEL_PII_03 3
-#define CPUID_MODEL_PII_05 5
-#define CPUID_MODEL_CELERON_06 6
-#define CPUID_MODEL_PM_09 9
-#define CPUID_MODEL_PM_0D 13
-#define CPUID_MODEL_PM_0E 14 // Yonah / Sossaman
-#define CPUID_MODEL_CORE_0F 15 // Conroe / Merom
-#define CPUID_MODEL_CORE_17 0x17 // Penryn
-#define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown
-#define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville
-#define CPUID_MODEL_CORE_1D 0x1d // Dunnington
-#define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield
-
-#define CPUID_MODEL_PIII_07 7
-#define CPUID_MODEL_PIII_08 8
-#define CPUID_MODEL_PIII_0A 10
-
-/* AMD model information */
-#define CPUID_MODEL_BARCELONA_02 0x02 // Barcelona (both Opteron & Phenom kind)
-
-/*
- *----------------------------------------------------------------------
- *
- * CPUID_IsVendor{AMD,Intel} --
- *
- * Determines if the vendor string in cpuid id0 is from {AMD,Intel}.
- *
- * Results:
- * True iff vendor string is CPUID_{AMD,INTEL}_VENDOR_STRING
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-static INLINE Bool
-CPUID_IsRawVendor(CPUIDRegs *id0, const char* vendor)
-{
- // hard to get strcmp() in some environments, so do it in the raw
- return (id0->ebx == *(const uint32 *) (vendor + 0) &&
- id0->ecx == *(const uint32 *) (vendor + 4) &&
- id0->edx == *(const uint32 *) (vendor + 8));
-}
-
-static INLINE Bool
-CPUID_IsVendorAMD(CPUIDRegs *id0)
-{
- return CPUID_IsRawVendor(id0, CPUID_AMD_VENDOR_STRING);
-}
-
-static INLINE Bool
-CPUID_IsVendorIntel(CPUIDRegs *id0)
-{
- return CPUID_IsRawVendor(id0, CPUID_INTEL_VENDOR_STRING);
-}
-
-
-static INLINE uint32
-CPUID_EFFECTIVE_FAMILY(uint32 v) /* %eax from CPUID with %eax=1. */
-{
- return CPUID_FAMILY(v) +
- (CPUID_FAMILY(v) == CPUID_FAMILY_EXTENDED ? CPUID_EXTENDED_FAMILY(v) : 0);
-}
-
-/* Normally only used when FAMILY==CPUID_FAMILY_EXTENDED, but Intel is
- * now using the extended model field for FAMILY==CPUID_FAMILY_P6 to
- * refer to the newer Core2 CPUs
- */
-static INLINE uint32
-CPUID_EFFECTIVE_MODEL(uint32 v) /* %eax from CPUID with %eax=1. */
-{
- return CPUID_MODEL(v) + (CPUID_EXTENDED_MODEL(v) << 4);
-}
-
-/*
- * Notice that CPUID families for Intel and AMD overlap. The following macros
- * should only be used AFTER the manufacturer has been established (through
- * the use of CPUID standard function 0).
- */
-static INLINE Bool
-CPUID_FAMILY_IS_486(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_486;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_P5(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P5;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_P6(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P6;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_PENTIUM4(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_P4;
-}
-
-/*
- * Intel Pentium M processors are Yonah/Sossaman or an older P-M
- */
-static INLINE Bool
-CPUID_UARCH_IS_PENTIUM_M(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /* Assumes the CPU manufacturer is Intel. */
- return CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_09 ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0D ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_PM_0E);
-}
-
-/*
- * Intel Core processors are Merom, Conroe, Woodcrest, Clovertown,
- * Penryn, Dunnington, Kentsfield, Yorktown, Harpertown, ........
- */
-static INLINE Bool
-CPUID_UARCH_IS_CORE(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- uint32 model = CPUID_EFFECTIVE_MODEL(v);
- /* Assumes the CPU manufacturer is Intel. */
- return CPUID_FAMILY_IS_P6(v) &&
- model >= CPUID_MODEL_CORE_0F &&
- (model < CPUID_MODEL_NEHALEM_1A ||
- model == CPUID_MODEL_CORE_1D);
-}
-
-/*
- * Intel Nehalem processors are: Nehalem, Gainestown, Lynnfield.
- */
-static INLINE Bool
-CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /* Assumes the CPU manufacturer is Intel. */
- return CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1A ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1E);
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K7(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K7;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8EXT(uint32 _eax)
-{
- /*
- * We check for this pattern often enough that it's
- * worth a separate function, for syntactic sugar.
- */
- return CPUID_FAMILY_IS_K8(_eax) &&
- CPUID_EXTENDED_MODEL(_eax) != 0;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8L(uint32 _eax)
-{
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8L;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8MOBILE(uint32 _eax)
-{
- /* Essentially a K8 (not K8L) part, but with mobile features. */
- return CPUID_EFFECTIVE_FAMILY(_eax) == CPUID_FAMILY_K8MOBILE;
-}
-
-static INLINE Bool
-CPUID_FAMILY_IS_K8STAR(uint32 _eax)
-{
- /*
- * Read function name as "K8*", as in wildcard.
- * Matches K8 or K8L or K8MOBILE
- */
- return CPUID_FAMILY_IS_K8(_eax) || CPUID_FAMILY_IS_K8L(_eax) ||
- CPUID_FAMILY_IS_K8MOBILE(_eax);
-}
-
-/*
- * AMD Barcelona (of either Opteron or Phenom kind).
- */
-static INLINE Bool
-CPUID_MODEL_IS_BARCELONA(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /* Assumes the CPU manufacturer is AMD. */
- return CPUID_FAMILY_IS_K8L(v) &&
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_BARCELONA_02;
-}
-
-
-#define CPUID_TYPE_PRIMARY 0
-#define CPUID_TYPE_OVERDRIVE 1
-#define CPUID_TYPE_SECONDARY 2
-
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_NULL 0
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_DATA 1
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_INST 2
-#define CPUID_INTEL_ID4EAX_CACHE_TYPE_UNIF 3
-
-#define CPUID_INTEL_ID4EAX_CACHE_SELF_INIT 0x00000100
-#define CPUID_INTEL_ID4EAX_CACHE_FULLY_ASSOC 0x00000200
-
-
-/*
- * On AMD chips before Opteron and Intel chips before P4 model 3,
- * WRMSR(TSC) clears the upper half of the TSC instead of using %edx.
- */
-static INLINE Bool
-CPUID_FullyWritableTSC(Bool isIntel, // IN
- uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- /*
- * Returns FALSE if:
- * - Intel && P6 (pre-core) or
- * - Intel && P4 (model < 3) or
- * - !Intel && pre-K8 Opteron
- * Otherwise, returns TRUE.
- */
- return !((isIntel &&
- ((CPUID_FAMILY_IS_P6(v) &&
- CPUID_EFFECTIVE_MODEL(v) < CPUID_MODEL_PM_0E) ||
- (CPUID_FAMILY_IS_PENTIUM4(v) &&
- CPUID_EFFECTIVE_MODEL(v) < 3))) ||
- (!isIntel &&
- CPUID_FAMILY(v) < CPUID_FAMILY_K8));
-}
-
-
-/*
- * For certain AMD processors, an lfence instruction is necessary at various
- * places to ensure ordering.
- */
-
-static INLINE Bool
-CPUID_VendorRequiresFence(CpuidVendors vendor)
-{
- return vendor == CPUID_VENDOR_AMD;
-}
-
-static INLINE Bool
-CPUID_VersionRequiresFence(uint32 version)
-{
- return CPUID_EFFECTIVE_FAMILY(version) == CPUID_FAMILY_K8 &&
- CPUID_EFFECTIVE_MODEL(version) < 0x40;
-}
-
-static INLINE Bool
-CPUID_ID0RequiresFence(CPUIDRegs *id0)
-{
- if (id0->eax == 0) {
- return FALSE;
- }
- return CPUID_IsVendorAMD(id0);
-}
-
-static INLINE Bool
-CPUID_ID1RequiresFence(CPUIDRegs *id1)
-{
- return CPUID_VersionRequiresFence(id1->eax);
-}
-
-static INLINE Bool
-CPUID_RequiresFence(CpuidVendors vendor, // IN
- uint32 version) // IN: %eax from CPUID with %eax=1.
-{
- return CPUID_VendorRequiresFence(vendor) &&
- CPUID_VersionRequiresFence(version);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * CPUID_CountsCPUIDAsBranch --
- *
- * Returns TRUE iff the cpuid given counts CPUID as a branch
- * (i.e. is a pre-Merom E CPU).
- *
- *----------------------------------------------------------------------
- */
-
-static INLINE Bool
-CPUID_CountsCPUIDAsBranch(uint32 v) /* %eax from CPUID with %eax=1 */
-{
- /*
- * CPUID no longer a branch starting with Merom E. Bug 148411.
- * Penryn (Extended Model: 1) also has this fixed.
- *
- * Merom E is: CPUID.1.eax & 0xfff = 0x6f9
- */
- return !(CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) > CPUID_MODEL_CORE_0F ||
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_CORE_0F &&
- CPUID_STEPPING(v) >= 9)));
-}
-
-/*
- * On Merom and later Intel chips, not present PDPTEs with reserved bits
- * set do not fault with a #GP. See PR# 109120.
- */
-static INLINE Bool
-CPUID_FaultOnNPReservedPDPTE(uint32 v) // IN: %eax from CPUID with %eax=1.
-{
- return !(CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) >= CPUID_MODEL_CORE_0F));
-}
-
-
-/*
- * The following low-level functions compute the number of
- * cores per cpu. They should be used cautiously because
- * they do not necessarily work on all types of CPUs.
- * High-level functions that are correct for all CPUs are
- * available elsewhere: see lib/cpuidInfo/cpuidInfo.c.
- */
-
-static INLINE uint32
-CPUID_IntelCoresPerPackage(uint32 v) /* %eax from CPUID with %eax=4 and %ecx=0. */
-{
- // Note: This is not guaranteed to work on older Intel CPUs.
- return 1 + CPUID_INTEL_CORE_COUNT(v);
-}
-
-static INLINE uint32
-CPUID_AMDCoresPerPackage(uint32 v) /* %ecx from CPUID with %eax=0x80000008. */
-{
- // Note: This is not guaranteed to work on older AMD CPUs.
- return 1 + CPUID_AMD_CORE_COUNT(v);
-}
-
-/*
- * Hypervisor CPUID space is 0x400000XX.
- */
-static INLINE Bool
-CPUID_IsHypervisorLevel(uint32 level, uint32 *offset)
-{
- *offset = level & 0xff;
- return (level & 0xffffff00) == 0x40000000;
-}
-
-
-#endif
#include "driver-config.h"
+#define EXPORT_SYMTAB
#include <linux/kmod.h>
#include <linux/socket.h>
#include <linux/net.h>
uint64 controlPacketCount[VSOCK_PACKET_TYPE_MAX];
uint64 consumeQueueLevel[VSOCK_NUM_QUEUE_LEVEL_BUCKETS];
uint64 produceQueueLevel[VSOCK_NUM_QUEUE_LEVEL_BUCKETS];
-#endif
+
+#define VSOCK_STATS_STREAM_CONSUME_HIST(vsk) \
+ VSockVmciUpdateQueueBucketCount((vsk)->consumeQ, \
+ (vsk)->produceQ, \
+ (vsk)->consumeSize, \
+ consumeQueueLevel)
+#define VSOCK_STATS_STREAM_PRODUCE_HIST(vsk) \
+ VSockVmciUpdateQueueBucketCount((vsk)->produceQ, \
+ (vsk)->consumeQ, \
+ (vsk)->produceSize, \
+ produceQueueLevel)
+#else
+#define VSOCK_STATS_STREAM_CONSUME_HIST(vsk)
+#define VSOCK_STATS_STREAM_PRODUCE_HIST(vsk)
+#endif // VSOCK_GATHER_STATISTICS
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5)
VSockVmciSendControlPkt(_sk, VSOCK_PACKET_TYPE_WAITING_READ, \
0, 0, _waitInfo, VMCI_INVALID_HANDLE)
-
#ifdef VMX86_LOG
# define LOG_PACKET(_pkt) VSockVmciLogPkt(__FUNCTION__, __LINE__, _pkt)
#else
exit:
up(®istrationMutex);
return afvalue;
+}
+EXPORT_SYMBOL(VMCISock_GetAFValue);
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMCISock_GetLocalCID --
+ *
+ * Kernel interface that allows external kernel modules to get the current
+ * VMCI context id.
+ * This version of the function is exported to kernel clients and should not
+ * change.
+ *
+ * Results:
+ * The context id on success, a negative error on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+VMCISock_GetLocalCID(void)
+{
+ int cid;
+
+ down(®istrationMutex);
+
+ /*
+ * Kernel clients are required to explicitly register themselves before they
+ * can use VMCI Sockets.
+ */
+ if (vsockVmciKernClientCount <= 0) {
+ cid = -1;
+ goto exit;
+ }
+
+ cid = VMCI_GetContextID();
+
+exit:
+ up(®istrationMutex);
+ return cid;
}
+EXPORT_SYMBOL(VMCISock_GetLocalCID);
/*
vsockVmciKernClientCount++;
up(®istrationMutex);
}
+EXPORT_SYMBOL(VMCISock_KernelRegister);
/*
VSockVmciTestUnregister();
up(®istrationMutex);
}
+EXPORT_SYMBOL(VMCISock_KernelDeregister);
/*
goto outWait;
}
-#if defined(VSOCK_GATHER_STATISTICS)
- VSockVmciUpdateQueueBucketCount(vsk->produceQ,
- vsk->consumeQ,
- vsk->produceSize,
- produceQueueLevel);
-#endif
+ VSOCK_STATS_STREAM_PRODUCE_HIST(vsk);
/*
* Note that enqueue will only write as many bytes as are free in the
err = 0;
goto outWait;
}
-#if defined(VSOCK_GATHER_STATISTICS)
- VSockVmciUpdateQueueBucketCount(vsk->consumeQ,
- vsk->produceQ,
- vsk->consumeSize,
- consumeQueueLevel);
-#endif
+ VSOCK_STATS_STREAM_CONSUME_HIST(vsk);
/*
* Now consume up to len bytes from the queue. Note that since we have the
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * vmciContext.h --
+ *
+ * VMCI state to enable sending calls between VMs.
+ */
+
+#ifndef _VMCI_CONTEXT_H_
+#define _VMCI_CONTEXT_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMMON
+#define INCLUDE_ALLOW_VMCORE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+#include "vmci_defs.h"
+#include "vmci_call_defs.h"
+#include "vmci_infrastructure.h"
+
+#define MAX_QUEUED_GUESTCALLS_PER_VM 100
+
+typedef struct VMCIContext VMCIContext;
+
+int VMCIContext_Init(void);
+void VMCIContext_Exit(void);
+int VMCIContext_InitContext(VMCIId cid, VMCIPrivilegeFlags flags,
+ uintptr_t eventHnd, VMCIContext **context);
+#ifdef VMKERNEL
+int VMCIContext_SetDomainName(VMCIContext *context, const char *domainName);
+int VMCIContext_GetDomainName(VMCIId contextID, char *domainName,
+ size_t domainNameBufSize);
+#endif
+void VMCIContext_ReleaseContext(VMCIContext *context);
+int VMCIContext_EnqueueDatagram(VMCIId cid, VMCIDatagram *dg);
+int VMCIContext_DequeueDatagram(VMCIContext *context, size_t *maxSize,
+ VMCIDatagram **dg);
+int VMCIContext_PendingDatagrams(VMCIId cid, uint32 *pending);
+VMCIContext *VMCIContext_Get(VMCIId cid);
+void VMCIContext_Release(VMCIContext *context);
+Bool VMCIContext_Exists(VMCIId cid);
+
+VMCIPrivilegeFlags VMCIContext_GetPrivFlags(VMCIId contextID);
+VMCIId VMCIContext_GetId(VMCIContext *context);
+int VMCIContext_AddGroupEntry(VMCIContext *context,
+ VMCIHandle entryHandle);
+VMCIHandle VMCIContext_RemoveGroupEntry(VMCIContext *context,
+ VMCIHandle entryHandle);
+int VMCIContext_AddWellKnown(VMCIId contextID, VMCIId wellKnownID);
+int VMCIContext_RemoveWellKnown(VMCIId contextID, VMCIId wellKnownID);
+int VMCIContext_AddNotification(VMCIId contextID, VMCIId remoteCID);
+int VMCIContext_RemoveNotification(VMCIId contextID, VMCIId remoteCID);
+int VMCIContext_GetCheckpointState(VMCIId contextID, uint32 cptType,
+ uint32 *numCIDs, char **cptBufPtr);
+int VMCIContext_SetCheckpointState(VMCIId contextID, uint32 cptType,
+ uint32 numCIDs, char *cptBuf);
+#ifndef VMX86_SERVER
+void VMCIContext_CheckAndSignalNotify(VMCIContext *context);
+# ifdef __linux__
+/* TODO Windows and Mac OS. */
+void VMCIUnsetNotify(VMCIContext *context);
+# endif
+#endif
+#endif // _VMCI_CONTEXT_H_
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * vmciDatagram.h --
+ *
+ * Internal functions in the VMCI Simple Datagram API.
+ */
+
+#ifndef _VMCI_DATAGRAM_H_
+#define _VMCI_DATAGRAM_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMMON
+#define INCLUDE_ALLOW_VMCORE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+#include "vmciContext.h"
+#include "vmci_call_defs.h"
+#ifndef VMX86_SERVER
+#include "vmci_iocontrols.h"
+#endif // !VMX86_SERVER
+
+typedef struct VMCIDatagramProcess VMCIDatagramProcess;
+
+/* Init functions. */
+int VMCIDatagram_Init(void);
+void VMCIDatagram_Exit(void);
+
+
+/* Datagram API for non-public use in host context*/
+int VMCIDatagramCreateHndInt(VMCIId resourceID, uint32 flags,
+ VMCIDatagramRecvCB recvCB, void *clientData,
+ VMCIHandle *outHandle);
+int VMCIDatagramCreateHndPriv(VMCIId resourceID, uint32 flags,
+ VMCIPrivilegeFlags privFlags,
+ VMCIDatagramRecvCB recvCB, void *clientData,
+ VMCIHandle *outHandle);
+int VMCIDatagramDestroyHndInt(VMCIHandle handle);
+int VMCIDatagram_Dispatch(VMCIId contextID, VMCIDatagram *dg);
+int VMCIDatagramSendInt(VMCIDatagram *msg);
+int VMCIDatagram_GetPrivFlags(VMCIHandle handle, VMCIPrivilegeFlags *privFlags);
+
+/* Non public datagram API. */
+int VMCIDatagramRequestWellKnownMap(VMCIId wellKnownID, VMCIId contextID,
+ VMCIPrivilegeFlags privFlags);
+int VMCIDatagramRemoveWellKnownMap(VMCIId wellKnownID, VMCIId contextID);
+
+#ifndef VMX86_SERVER
+/* Userlevel process datagram API for host context. */
+int VMCIDatagramProcess_Create(VMCIDatagramProcess **outDgmProc,
+ VMCIDatagramCreateInfo *createInfo);
+void VMCIDatagramProcess_Destroy(VMCIDatagramProcess *dgmProc);
+int VMCIDatagramProcess_ReadCall(VMCIDatagramProcess *dgmProc,
+ size_t maxSize, VMCIDatagram **dg);
+#endif // !VMX86_SERVER
+
+#endif // _VMCI_DATAGRAM_H_
+
+
*
*********************************************************/
-/*
+/*
* vmciHostKernelAPI.h --
*
* Kernel API exported from the VMCI host driver.
#endif
#include "vmci_call_defs.h"
-#if (defined(__linux__) || defined(_WIN32)) && !defined(VMKERNEL)
+#if !defined(VMKERNEL)
#include "vmci_queue_pair.h"
#endif
typedef struct VMCIQueue {
uint32 offset; // Start page of queue in backing store
- uint32 len; // Number of pages in the queue
+ uint32 len; // Number of pages in the queue
struct QueuePairEntry *entry; // Endpoint state for the queue pair
} VMCIQueue;
size_t bufSize, Util_BufferType bufType);
#endif /* VMKERNEL */
-#if defined(VMKERNEL) || defined(__linux__) || defined(_WIN32)
int VMCIQueuePair_Alloc(VMCIHandle *handle, VMCIQueue **produceQ,
uint64 produceSize, VMCIQueue **consumeQ,
uint64 consumeSize, VMCIId peer, uint32 flags);
int VMCIQueuePair_Detach(VMCIHandle handle);
-#endif
#endif /* !__VMCI_HOSTKERNELAPI_H__ */
#if defined(_WIN32)
-# include <winsock2.h>
+# if !defined(_DDK_DRIVER_)
+# include <winsock2.h>
+# endif // _DDK_DRIVER_
#else // _WIN32
#if defined(linux) && !defined(VMKERNEL)
-# if defined(__KERNEL__)
-# include "driver-config.h"
-# include "compat_sock.h"
-# else
+# if !defined(__KERNEL__)
# include <sys/socket.h>
# endif // __KERNEL__
#else // linux && !VMKERNEL
#if defined(_WIN32)
-# if !defined(WINNT_DDK)
-# include <winioctl.h>
-# define VMCI_SOCKETS_DEVICE L"\\\\.\\VMCI"
-# define VMCI_SOCKETS_GET_AF_VALUE 0x81032068
-# define VMCI_SOCKETS_GET_LOCAL_CID 0x8103206c
-
- static __inline int VMCISock_GetAFValue(void)
- {
- HANDLE device = CreateFileW(VMCI_SOCKETS_DEVICE, GENERIC_READ, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (INVALID_HANDLE_VALUE != device) {
- DWORD ioReturn;
- int afvalue;
- if (DeviceIoControl(device, VMCI_SOCKETS_GET_AF_VALUE, &afvalue,
- sizeof afvalue, &afvalue, sizeof afvalue,
- &ioReturn, NULL)) {
+# if !defined(_DDK_DRIVER_)
+# include <winioctl.h>
+# define VMCI_SOCKETS_DEVICE L"\\\\.\\VMCI"
+# define VMCI_SOCKETS_GET_AF_VALUE 0x81032068
+# define VMCI_SOCKETS_GET_LOCAL_CID 0x8103206c
+ static __inline int VMCISock_GetAFValue(void)
+ {
+ int afvalue = -1;
+ HANDLE device = CreateFileW(VMCI_SOCKETS_DEVICE, GENERIC_READ, 0, NULL,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ if (INVALID_HANDLE_VALUE != device) {
+ DWORD ioReturn;
+ DeviceIoControl(device, VMCI_SOCKETS_GET_AF_VALUE, &afvalue,
+ sizeof afvalue, &afvalue, sizeof afvalue,
+ &ioReturn, NULL);
CloseHandle(device);
device = INVALID_HANDLE_VALUE;
- return afvalue;
}
- CloseHandle(device);
- device = INVALID_HANDLE_VALUE;
+ return afvalue;
}
- return -1;
- }
-
- static __inline unsigned int VMCISock_GetLocalCID(void)
- {
- HANDLE device = CreateFileW(VMCI_SOCKETS_DEVICE, GENERIC_READ, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (INVALID_HANDLE_VALUE != device) {
- DWORD ioReturn;
- unsigned int cid;
- if (DeviceIoControl(device, VMCI_SOCKETS_GET_LOCAL_CID, &cid,
- sizeof cid, &cid, sizeof cid, &ioReturn,
- NULL)) {
+
+ static __inline unsigned int VMCISock_GetLocalCID(void)
+ {
+ unsigned int cid = VMADDR_CID_ANY;
+ HANDLE device = CreateFileW(VMCI_SOCKETS_DEVICE, GENERIC_READ, 0, NULL,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ if (INVALID_HANDLE_VALUE != device) {
+ DWORD ioReturn;
+ DeviceIoControl(device, VMCI_SOCKETS_GET_LOCAL_CID, &cid,
+ sizeof cid, &cid, sizeof cid, &ioReturn,
+ NULL);
CloseHandle(device);
device = INVALID_HANDLE_VALUE;
- return cid;
}
- CloseHandle(device);
- device = INVALID_HANDLE_VALUE;
+ return cid;
}
- return VMADDR_CID_ANY;
- }
-# endif // WINNT_DDK
+# endif // _DDK_DRIVER_
#else // _WIN32
#if defined(linux) && !defined(VMKERNEL)
# ifdef __KERNEL__
void VMCISock_KernelRegister(void);
void VMCISock_KernelDeregister(void);
int VMCISock_GetAFValue(void);
+ int VMCISock_GetLocalCID(void);
# else // __KERNEL__
# include <sys/types.h>
# include <sys/stat.h>
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * vmci_sockets_int.h --
+ *
+ * VMCI sockets private constants and types.
+ *
+ * This file is internal only, we do not ship the kernel interface yet.
+ * You need to include this file *before* vmci_sockets.h in your kernel
+ * module.
+ */
+
+#ifndef _VMCI_SOCKETS_INT_H_
+#define _VMCI_SOCKETS_INT_H_
+
+
+#if defined(_WIN32)
+# if defined(_DDK_DRIVER_)
+ /*
+ * WinSockKernel is targetted at Vista and later. We want to allow
+ * drivers built from W2K onwards to work with the interface. Until we
+ * find a better way, these hacks are necessary.
+ */
+ typedef unsigned short u_short;
+# include <windef.h>
+# include <ws2def.h>
+ typedef WSACMSGHDR CMSGHDR, *PCMSGHDR;
+# include <wsk.h>
+ NTSTATUS VMCISock_WskRegister(PWSK_CLIENT_NPI wskClientNpi,
+ PWSK_REGISTRATION wskRegistration);
+ NTSTATUS VMCISock_WskDeregister(PWSK_REGISTRATION wskRegistration);
+ NTSTATUS VMCISock_WskCaptureProviderNPI(PWSK_REGISTRATION wskRegistration,
+ ULONG waitTimeout,
+ PWSK_PROVIDER_NPI wskProviderNpi);
+ NTSTATUS VMCISock_WskReleaseProviderNPI(PWSK_REGISTRATION wskRegistration);
+ NTSTATUS VMCISock_WskGetAFValue(PWSK_CLIENT wskClient, PIRP irp);
+ NTSTATUS VMCISock_WskGetLocalCID(PWSK_CLIENT wskClient, PIRP irp);
+# endif // _DDK_DRIVER_
+#endif // _WIN32
+
+/*
+ * Wrapper functions around common socket functions. On OS X we need to wrap
+ * these functions in order to workaround the lack of pluggable socket families in
+ * OS X.
+ */
+
+#if defined(__APPLE__)
+
+# if !defined(KERNEL)
+# include <sys/socket.h>
+
+ int VMCISock_APIInit();
+ int VMCISock_socket(int domain, int type, int protocol);
+ int VMCISock_bind(int socket, const struct sockaddr *address, socklen_t address_len);
+ int VMCISock_listen(int socket, int backlog);
+ int VMCISock_accept(int socket, struct sockaddr * address, socklen_t * address_len);
+ int VMCISock_getsockname(int socket, struct sockaddr * address, socklen_t * address_len);
+ int VMCISock_connect(int socket, const struct sockaddr *address, socklen_t address_len);
+ int VMCISock_close(int socket);
+ ssize_t VMCISock_send(int socket, const void *buffer, size_t length, int flags);
+ ssize_t VMCISock_recv(int socket, void *buffer, size_t length, int flags);
+ ssize_t VMCISock_sendto(int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
+ ssize_t VMCISock_recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len);
+# endif // KERNEL
+#else
+# define VMCISock_APIInit()
+# define VMCISock_socket(_domain, _type, _protocol) socket(_domain, _type, _protocol)
+# define VMCISock_bind(_socket, _address, _address_len) bind(_socket, _address, _address_len)
+# define VMCISock_listen(_socket, _backlog) listen(_socket, _backlog)
+# define VMCISock_accept(_socket, _address, _address_len) accept(_socket, _address, _address_len)
+# define VMCISock_getsockname(_socket, _address, _address_len) getsockname(_socket, _address, _address_len)
+# define VMCISock_connect(_socket, _address, _address_len) connect(_socket, _address, _address_len)
+# define VMCISock_send(_socket, _buffer, _length, _flags) send(_socket, _buffer, _length, _flags)
+# define VMCISock_recv(_socket, _buffer, _length, _flags) recv(_socket, _buffer, _length, _flags)
+# define VMCISock_sendto(_socket, _buffer, _length, _flags, _dest_addr, _dest_len) sendto(_socket, _buffer, _length, _flags, _dest_addr, _dest_len)
+# define VMCISock_recvfrom(_socket, _buffer, _length, _flags, _address, _address_len) recvfrom(_socket, _buffer, _length, _flags, _address, _address_len)
+#endif // __APPLE__
+
+#endif // _VMCI_SOCKETS_INT_H_
+
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmci_sockets_kernel.h --
- *
- * VMCI sockets kernel public constants and types.
- */
-
-#ifndef _VMCI_SOCKETS_KERNEL_H_
-#define _VMCI_SOCKETS_KERNEL_H_
-
-
-#include "vmci_sockets.h"
-
-
-#if defined(_WIN32)
-# if defined(WINNT_DDK)
- typedef WSACMSGHDR CMSGHDR, *PCMSGHDR;
-# include <wsk.h>
- NTSTATUS VMCISock_WskRegister(PWSK_CLIENT_NPI wskClientNpi,
- PWSK_REGISTRATION wskRegistration);
- NTSTATUS VMCISock_WskDeregister(PWSK_REGISTRATION wskRegistration);
- NTSTATUS VMCISock_WskCaptureProviderNPI(PWSK_REGISTRATION wskRegistration,
- ULONG waitTimeout,
- PWSK_PROVIDER_NPI wskProviderNpi);
- NTSTATUS VMCISock_WskReleaseProviderNPI(PWSK_REGISTRATION wskRegistration);
-# endif // WINNT_DDK
-#endif // _WIN32
-
-
-#endif // _VMCI_SOCKETS_KERNEL_H_
-
#elif defined(VMKERNEL)
# include "vm_libc.h"
# include "return_status.h"
+#elif defined(__APPLE__)
+# include <sys/errno.h>
#endif
#include "vsockCommon.h"
# define VMCI_SOCKETS_AF_VALUE 28
# if defined(WINNT_DDK)
# define _WIN2K_COMPAT_SLIST_USAGE
- /*
- * wdm.h has to come first, otherwise NTDDI_VERSION gets all confused
- * and we start pulling in the wrong versions of the Ke() routines.
- */
-# include <wdm.h>
# include <ntddk.h>
# include <windef.h>
- /*
- * Using ntifs.h for these functions does not play nicely with having
- * wdm.h first. So rather than include that header, we pull these in
- * directly.
- */
- NTKERNELAPI HANDLE PsGetCurrentProcessId(VOID);
- NTKERNELAPI NTSTATUS PsSetCreateProcessNotifyRoutine(
- PCREATE_PROCESS_NOTIFY_ROUTINE, BOOLEAN);
- NTSYSAPI NTSTATUS NTAPI
- ZwWaitForSingleObject(HANDLE, BOOLEAN, PLARGE_INTEGER);
# define _INC_WINDOWS
-# include "vmci_queue_pair.h"
/* In the kernel we can't call into the provider. */
# define VMCISockGetAFValueInt() VMCI_SOCKETS_AF_VALUE
# else // WINNT_DDK
/* In userland, just use the normal exported userlevel api. */
# define VMCISockGetAFValueInt() VMCISock_GetAFValue()
# endif
+#else
+#if defined(__APPLE__)
+# if defined(KERNEL)
+# include "vmci_queue_pair.h"
+
+/*
+ * XXX: These defines are NOT 64 bit safe - they need to be revisited as part
+ * of any work to support 64 bit kernels.
+ */
+# define Uint64ToPtr(_ui) ((void *)(uint32)(_ui))
+# define PtrToUint64(_p) ((uint64)(_p))
+
+# define VMCI_SOCKETS_AF_VALUE PF_SYSTEM
+# define VMCISockGetAFValueInt() VMCI_SOCKETS_AF_VALUE
+# else // KERNEL
+# define VMCISockGetAFValueInt() VMCISock_GetAFValue()
+# endif // KERNEL
+#endif // __APPLE__
#endif // linux
#endif // VMKERNEL
#endif // _WIN32
#include "vmware_pack_init.h"
#include "vmci_defs.h"
#include "vmci_call_defs.h"
+#include "vmci_sockets_int.h"
#include "vmci_sockets.h"
-#include "vmci_sockets_kernel.h"
+
+#if defined(WINNT_DDK)
+# include <winsock2.h>
+#endif // WINNT_DDK
+
#include "vsockAddr.h"
#include "vsockSocketWrapper.h"
# endif
#endif
-#if defined(_WIN32) || defined(VMKERNEL)
+#if defined __APPLE__
+# define MSG_NOSIGNAL 0
+#endif // __APPLE__
+
+#if defined(_WIN32) || defined(VMKERNEL) || defined __APPLE__
# define SS_FREE 0
# define SS_UNCONNECTED 1
# define SS_CONNECTING 2
# define SOCKET_EVENT_CONNECT FD_CONNECT
# define SOCKET_EVENT_CLOSE FD_CLOSE
#else
-#if defined(VMKERNEL)
+#if defined(VMKERNEL) || defined(__APPLE__)
# define SOCKET_EVENT_READ 0x1
# define SOCKET_EVENT_WRITE 0x2
# define SOCKET_EVENT_ACCEPT 0x8
# define __ELOCALSHUTDOWN EPIPE
# define __EPEERSHUTDOWN EPIPE
# define __ECONNINPROGRESS EINPROGRESS
+#else
+#if defined(__APPLE__)
+# define __ELOCALSHUTDOWN ESHUTDOWN
+# define __EPEERSHUTDOWN ECONNABORTED
+# define __ECONNINPROGRESS EINPROGRESS
+#endif // __APPLE
#endif // VMKERNEL
#endif // _WIN32
# define closesocket(_s) close((_s))
typedef int32 SOCKET;
#else
-#if defined(linux)
+#if defined(linux) || defined(__APPLE__)
# define SOCKET_ERROR (-1)
# define INVALID_SOCKET ((SOCKET) -1)
# define sockerr() errno
# define sockerr2err(_e) (((_e) > 0) ? -(_e) : (_e))
# define sockcleanup() do {} while (0)
+#if defined(linux)
# define closesocket(_s) close((_s))
+#else
+# define closesocket(_s) VMCISock_close(_s)
+#endif
typedef int32 SOCKET;
#endif // linux
#endif // VMKERNEL
--- /dev/null
+
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+
+1. Definitions.
+
+ 1.1. "Contributor" means each individual or entity that creates
+ or contributes to the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Software, prior Modifications used by a Contributor (if any),
+ and the Modifications made by that particular Contributor.
+
+ 1.3. "Covered Software" means (a) the Original Software, or (b)
+ Modifications, or (c) the combination of files containing
+ Original Software with files containing Modifications, in
+ each case including portions thereof.
+
+ 1.4. "Executable" means the Covered Software in any form other
+ than Source Code.
+
+ 1.5. "Initial Developer" means the individual or entity that first
+ makes Original Software available under this License.
+
+ 1.6. "Larger Work" means a work which combines Covered Software or
+ portions thereof with code not governed by the terms of this
+ License.
+
+ 1.7. "License" means this document.
+
+ 1.8. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed
+ herein.
+
+ 1.9. "Modifications" means the Source Code and Executable form of
+ any of the following:
+
+ A. Any file that results from an addition to, deletion from or
+ modification of the contents of a file containing Original
+ Software or previous Modifications;
+
+ B. Any new file that contains any part of the Original
+ Software or previous Modifications; or
+
+ C. Any new file that is contributed or otherwise made
+ available under the terms of this License.
+
+ 1.10. "Original Software" means the Source Code and Executable
+ form of computer software code that is originally released
+ under this License.
+
+ 1.11. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by
+ grantor.
+
+ 1.12. "Source Code" means (a) the common form of computer software
+ code in which modifications are made and (b) associated
+ documentation included in or with such code.
+
+ 1.13. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms
+ of, this License. For legal entities, "You" includes any
+ entity which controls, is controlled by, or is under common
+ control with You. For purposes of this definition,
+ "control" means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty
+ percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, the Initial
+ Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer, to use,
+ reproduce, modify, display, perform, sublicense and
+ distribute the Original Software (or portions thereof),
+ with or without Modifications, and/or as part of a Larger
+ Work; and
+
+ (b) under Patent Claims infringed by the making, using or
+ selling of Original Software, to make, have made, use,
+ practice, sell, and offer for sale, and/or otherwise
+ dispose of the Original Software (or portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ or otherwise makes the Original Software available to a
+ third party under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: (1) for code that You delete from the Original
+ Software, or (2) for infringements caused by: (i) the
+ modification of the Original Software, or (ii) the
+ combination of the Original Software with other software
+ or devices.
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, each
+ Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor to use, reproduce,
+ modify, display, perform, sublicense and distribute the
+ Modifications created by such Contributor (or portions
+ thereof), either on an unmodified basis, with other
+ Modifications, as Covered Software and/or as part of a
+ Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either
+ alone and/or in combination with its Contributor Version
+ (or portions of such combination), to make, use, sell,
+ offer for sale, have made, and/or otherwise dispose of:
+ (1) Modifications made by that Contributor (or portions
+ thereof); and (2) the combination of Modifications made by
+ that Contributor with its Contributor Version (or portions
+ of such combination).
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first distributes or
+ otherwise makes the Modifications available to a third
+ party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: (1) for any code that Contributor has deleted
+ from the Contributor Version; (2) for infringements caused
+ by: (i) third party modifications of Contributor Version,
+ or (ii) the combination of Modifications made by that
+ Contributor with other software (except as part of the
+ Contributor Version) or other devices; or (3) under Patent
+ Claims infringed by Covered Software in the absence of
+ Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+
+ Any Covered Software that You distribute or otherwise make
+ available in Executable form must also be made available in Source
+ Code form and that Source Code form must be distributed only under
+ the terms of this License. You must include a copy of this
+ License with every copy of the Source Code form of the Covered
+ Software You distribute or otherwise make available. You must
+ inform recipients of any such Covered Software in Executable form
+ as to how they can obtain such Covered Software in Source Code
+ form in a reasonable manner on or through a medium customarily
+ used for software exchange.
+
+ 3.2. Modifications.
+
+ The Modifications that You create or to which You contribute are
+ governed by the terms of this License. You represent that You
+ believe Your Modifications are Your original creation(s) and/or
+ You have sufficient rights to grant the rights conveyed by this
+ License.
+
+ 3.3. Required Notices.
+
+ You must include a notice in each of Your Modifications that
+ identifies You as the Contributor of the Modification. You may
+ not remove or alter any copyright, patent or trademark notices
+ contained within the Covered Software, or any notices of licensing
+ or any descriptive text giving attribution to any Contributor or
+ the Initial Developer.
+
+ 3.4. Application of Additional Terms.
+
+ You may not offer or impose any terms on any Covered Software in
+ Source Code form that alters or restricts the applicable version
+ of this License or the recipients' rights hereunder. You may
+ choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of
+ Covered Software. However, you may do so only on Your own behalf,
+ and not on behalf of the Initial Developer or any Contributor.
+ You must make it absolutely clear that any such warranty, support,
+ indemnity or liability obligation is offered by You alone, and You
+ hereby agree to indemnify the Initial Developer and every
+ Contributor for any liability incurred by the Initial Developer or
+ such Contributor as a result of warranty, support, indemnity or
+ liability terms You offer.
+
+ 3.5. Distribution of Executable Versions.
+
+ You may distribute the Executable form of the Covered Software
+ under the terms of this License or under the terms of a license of
+ Your choice, which may contain terms different from this License,
+ provided that You are in compliance with the terms of this License
+ and that the license for the Executable form does not attempt to
+ limit or alter the recipient's rights in the Source Code form from
+ the rights set forth in this License. If You distribute the
+ Covered Software in Executable form under a different license, You
+ must make it absolutely clear that any terms which differ from
+ this License are offered by You alone, not by the Initial
+ Developer or Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred
+ by the Initial Developer or such Contributor as a result of any
+ such terms You offer.
+
+ 3.6. Larger Works.
+
+ You may create a Larger Work by combining Covered Software with
+ other code not governed by the terms of this License and
+ distribute the Larger Work as a single product. In such a case,
+ You must make sure the requirements of this License are fulfilled
+ for the Covered Software.
+
+4. Versions of the License.
+
+ 4.1. New Versions.
+
+ Sun Microsystems, Inc. is the initial license steward and may
+ publish revised and/or new versions of this License from time to
+ time. Each version will be given a distinguishing version number.
+ Except as provided in Section 4.3, no one other than the license
+ steward has the right to modify this License.
+
+ 4.2. Effect of New Versions.
+
+ You may always continue to use, distribute or otherwise make the
+ Covered Software available under the terms of the version of the
+ License under which You originally received the Covered Software.
+ If the Initial Developer includes a notice in the Original
+ Software prohibiting it from being distributed or otherwise made
+ available under any subsequent version of the License, You must
+ distribute and make the Covered Software available under the terms
+ of the version of the License under which You originally received
+ the Covered Software. Otherwise, You may also choose to use,
+ distribute or otherwise make the Covered Software available under
+ the terms of any subsequent version of the License published by
+ the license steward.
+
+ 4.3. Modified Versions.
+
+ When You are an Initial Developer and You want to create a new
+ license for Your Original Software, You may create and use a
+ modified version of this License if You: (a) rename the license
+ and remove any references to the name of the license steward
+ (except to note that the license differs from this License); and
+ (b) otherwise make it clear that the license contains terms which
+ differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
+ BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
+ SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
+ PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
+ PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
+ COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+ INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
+ NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
+ WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
+ DISCLAIMER.
+
+6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to
+ cure such breach within 30 days of becoming aware of the breach.
+ Provisions which, by their nature, must remain in effect beyond
+ the termination of this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding
+ declaratory judgment actions) against Initial Developer or a
+ Contributor (the Initial Developer or Contributor against whom You
+ assert such claim is referred to as "Participant") alleging that
+ the Participant Software (meaning the Contributor Version where
+ the Participant is a Contributor or the Original Software where
+ the Participant is the Initial Developer) directly or indirectly
+ infringes any patent, then any and all rights granted directly or
+ indirectly to You by such Participant, the Initial Developer (if
+ the Initial Developer is not the Participant) and all Contributors
+ under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
+ notice from Participant terminate prospectively and automatically
+ at the expiration of such 60 day notice period, unless if within
+ such 60 day period You withdraw Your claim with respect to the
+ Participant Software against such Participant either unilaterally
+ or pursuant to a written agreement with Participant.
+
+ 6.3. In the event of termination under Sections 6.1 or 6.2 above,
+ all end user licenses that have been validly granted by You or any
+ distributor hereunder prior to termination (excluding licenses
+ granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+ INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+ COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
+ LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
+ CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+ LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
+ STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+ INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
+ APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
+ NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
+ APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a "commercial item," as that term is
+ defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
+ computer software" (as that term is defined at 48
+ C.F.R. 252.227-7014(a)(1)) and "commercial computer software
+ documentation" as such terms are used in 48 C.F.R. 12.212
+ (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
+ C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
+ U.S. Government End Users acquire Covered Software with only those
+ rights set forth herein. This U.S. Government Rights clause is in
+ lieu of, and supersedes, any other FAR, DFAR, or other clause or
+ provision that addresses Government rights in computer software
+ under this License.
+
+9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed
+ by the law of the jurisdiction specified in a notice contained
+ within the Original Software (except to the extent applicable law,
+ if any, provides otherwise), excluding such jurisdiction's
+ conflict-of-law provisions. Any litigation relating to this
+ License shall be subject to the jurisdiction of the courts located
+ in the jurisdiction and venue specified in a notice contained
+ within the Original Software, with the losing party responsible
+ for costs, including, without limitation, court costs and
+ reasonable attorneys' fees and expenses. The application of the
+ United Nations Convention on Contracts for the International Sale
+ of Goods is expressly excluded. Any law or regulation which
+ provides that the language of a contract shall be construed
+ against the drafter shall not apply to this License. You agree
+ that You alone are responsible for compliance with the United
+ States export administration regulations (and the export control
+ laws and regulation of any other countries) when You use,
+ distribute or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or
+ indirectly, out of its utilization of rights under this License
+ and You agree to work with Initial Developer and Contributors to
+ distribute such responsibility on an equitable basis. Nothing
+ herein is intended or shall be deemed to constitute any admission
+ of liability.
+
--- /dev/null
+#!/usr/bin/make -f
+##########################################################
+# Copyright (C) 2009 VMware, Inc. All rights reserved.
+#
+# The contents of this file are subject to the terms of the Common
+# Development and Distribution License (the "License") version 1.0
+# and no later version. You may not use this file except in
+# compliance with the License.
+#
+# You can obtain a copy of the License at
+# http://www.opensource.org/licenses/cddl1.php
+#
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+##########################################################
+
+##
+## General build locations and variables
+##
+
+MODULE := vmblock
+CFLAGS :=
+LDFLAGS :=
+
+# Solaris version defines for in-code #ifdefs (default to Solaris 9)
+ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.11)
+CFLAGS += -DSOL11
+else
+ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.10)
+CFLAGS += -DSOL10
+else
+CFLAGS += -DSOL9
+# we don't support Solaris 9 (we could but we use memcpy/memset
+# and we'd need stubs to get the module to load into the kernel).
+$(error "This makefile is only used for Solaris 10 and 11")
+endif
+endif
+
+CFLAGS += -ffreestanding
+CFLAGS += -nodefaultlibs
+
+CFLAGS += -O2
+CFLAGS += -Wall -Werror
+CFLAGS += -I.
+
+##
+## Objects needed to build vmblock kernel module
+##
+VMBLOCK_OBJS := block.o
+VMBLOCK_OBJS += dbllnklst.o
+VMBLOCK_OBJS += module.o
+VMBLOCK_OBJS += stubs.o
+VMBLOCK_OBJS += vfsops.o
+VMBLOCK_OBJS += vnops.o
+
+VMBLOCK_32_OBJS := $(addprefix i386/, $(VMBLOCK_OBJS))
+VMBLOCK_64_OBJS := $(addprefix amd64/, $(VMBLOCK_OBJS))
+
+MODULE_32 := i386/$(MODULE)
+MODULE_64 := amd64/$(MODULE)
+
+CFLAGS_32 := $(CFLAGS)
+CFLAGS_32 += -m32
+LDFLAGS_32 := $(LDFLAGS)
+
+CFLAGS_64 := $(CFLAGS)
+CFLAGS_64 += -m64
+CFLAGS_64 += -mcmodel=kernel
+CFLAGS_64 += -mno-red-zone
+LDFLAGS_64 := $(LDFLAGS)
+ifdef HAVE_GNU_LD
+LDFLAGS_64 += -m elf_x86_64
+else
+LDFLAGS_64 += -64
+endif
+
+##
+## Building targets
+##
+.PHONY: all prepare_dirs clean install
+
+all: prepare_dirs $(MODULE_32) $(MODULE_64)
+
+prepare_dirs:
+ @echo "Creating build directories"
+ mkdir -p i386
+ mkdir -p amd64
+
+# Build just the module for 32 bits kernel
+$(MODULE_32): $(VMBLOCK_32_OBJS)
+ @echo "Linking $(MODULE_32)"
+ $(LD) $(LDFLAGS_32) -r -o $(MODULE_32) $(VMBLOCK_32_OBJS)
+
+$(VMBLOCK_32_OBJS): i386/%.o: %.c
+ @echo "Compiling $(<F)"
+ $(CC) $(CFLAGS_32) -D_KERNEL -c $< -o $@
+
+# Now the same for 64 bits kernel
+$(MODULE_64): $(VMBLOCK_64_OBJS)
+ @echo "Linking $(MODULE_64)"
+ $(LD) $(LDFLAGS_64) -r -o $(MODULE_64) $(VMBLOCK_64_OBJS)
+
+$(VMBLOCK_64_OBJS): amd64/%.o: %.c
+ @echo "Compiling $(<F)"
+ $(CC) $(CFLAGS_64) -D_KERNEL -c $< -o $@
+
+clean:
+ @echo "Cleaning directories"
+ @rm -rf $(MODULE_32) $(VMBLOCK_32_OBJS) i386
+ @rm -rf $(MODULE_64) $(VMBLOCK_32_OBJS) amd64
+
+install:
+ @echo "Installing modules"
+ cp $(MODULE_32) /kernel/drv/
+ chmod 755 /kernel/drv/$(MODULE)
+ cp $(MODULE_64) /kernel/drv/amd64
+ chmod 755 /kernel/drv/amd64/$(MODULE)
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * block.c --
+ *
+ * Blocking operation implementions for the vmblock driver.
+ */
+
+/* os.h includes necessary OS-specific headers. */
+#include "os.h"
+
+#if defined(vmblock_fuse)
+#elif defined(linux)
+# include "vmblockInt.h"
+#elif defined(sun)
+# include "module.h"
+#elif defined(__FreeBSD__)
+# include "vmblock_k.h"
+#endif
+#include "block.h"
+#include "stubs.h"
+#include "dbllnklst.h"
+
+typedef struct BlockInfo {
+ DblLnkLst_Links links;
+ os_atomic_t refcount;
+ os_blocker_id_t blocker;
+ os_completion_t completion;
+ char filename[OS_PATH_MAX];
+} BlockInfo;
+
+
+/* XXX: Is it worth turning this into a hash table? */
+static DblLnkLst_Links blockedFiles;
+static os_rwlock_t blockedFilesLock;
+static os_kmem_cache_t *blockInfoCache = NULL;
+
+/* Utility functions */
+static Bool BlockExists(const char *filename);
+static BlockInfo *GetBlock(const char *filename, const os_blocker_id_t blocker);
+static BlockInfo *AllocBlock(os_kmem_cache_t *cache,
+ const char *filename, const os_blocker_id_t blocker);
+static void FreeBlock(os_kmem_cache_t *cache, BlockInfo *block);
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockInit --
+ *
+ * Initializes blocking portion of module.
+ *
+ * Results:
+ * Zero on success, error code on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+BlockInit(void)
+{
+ ASSERT(!blockInfoCache);
+
+ blockInfoCache = os_kmem_cache_create("blockInfoCache",
+ sizeof (BlockInfo),
+ 0,
+ NULL);
+ if (!blockInfoCache) {
+ return OS_ENOMEM;
+ }
+
+ DblLnkLst_Init(&blockedFiles);
+ os_rwlock_init(&blockedFilesLock);
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockCleanup --
+ *
+ * Cleans up the blocking portion of the module.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+BlockCleanup(void)
+{
+ ASSERT(blockInfoCache);
+ ASSERT(!DblLnkLst_IsLinked(&blockedFiles));
+
+ os_rwlock_destroy(&blockedFilesLock);
+ os_kmem_cache_destroy(blockInfoCache);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockAddFileBlock --
+ *
+ * Adds a block for the provided filename. filename should be the name of
+ * the actual file being blocked, not the name within our namespace. The
+ * provided blocker ID should uniquely identify this blocker.
+ *
+ * All calls to BlockWaitOnFile() with the same filename will not return
+ * until BlockRemoveFileBlock() is called.
+ *
+ * Note that this function assumes a block on filename does not already
+ * exist.
+ *
+ * Results:
+ * Zero on success, error code on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+BlockAddFileBlock(const char *filename, // IN: name of file to block
+ const os_blocker_id_t blocker) // IN: blocker adding the block
+{
+ BlockInfo *block;
+
+ ASSERT(filename);
+
+ /* Create a new block. */
+ block = AllocBlock(blockInfoCache, filename, blocker);
+ if (!block) {
+ Warning("BlockAddFileBlock: out of memory\n");
+ return OS_ENOMEM;
+ }
+ os_write_lock(&blockedFilesLock);
+
+ /*
+ * Prevent duplicate blocks of any filename. Done under same lock as list
+ * addition to ensure check for and adding of file are atomic.
+ */
+ if (BlockExists(filename)) {
+ Warning("BlockAddFileBlock: block already exists for [%s]\n", filename);
+ os_write_unlock(&blockedFilesLock);
+ FreeBlock(blockInfoCache, block);
+ return OS_EEXIST;
+ }
+
+ DblLnkLst_LinkLast(&blockedFiles, &block->links);
+
+ os_write_unlock(&blockedFilesLock);
+
+ LOG(4, "added block for [%s]\n", filename);
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockRemoveFileBlock --
+ *
+ * Removes the provided file block and wakes up any threads waiting within
+ * BlockWaitOnFile(). Note that only the blocker that added a block can
+ * remove it.
+ *
+ * Results:
+ * Zero on success, error code on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+BlockRemoveFileBlock(const char *filename, // IN: block to remove
+ const os_blocker_id_t blocker) // IN: blocker removing this block
+{
+ BlockInfo *block;
+
+ ASSERT(filename);
+
+ os_write_lock(&blockedFilesLock);
+
+ block = GetBlock(filename, blocker);
+ if (!block) {
+ os_write_unlock(&blockedFilesLock);
+ return OS_ENOENT;
+ }
+
+ DblLnkLst_Unlink1(&block->links);
+ os_write_unlock(&blockedFilesLock);
+
+ /* Undo GetBlock's refcount increment first. */
+ os_atomic_dec(&block->refcount);
+
+ /*
+ * Now remove /our/ reference. (As opposed to references by waiting
+ * threads.)
+ */
+ if (os_atomic_dec_and_test(&block->refcount)) {
+ /* No threads are waiting, so clean up ourself. */
+ LOG(4, "Freeing block with no waiters on [%s]\n", filename);
+ FreeBlock(blockInfoCache, block);
+ } else {
+ /* Wake up waiters; the last one will free the BlockInfo */
+ LOG(4, "Completing block on [%s]\n", filename);
+ os_complete_all(&block->completion);
+ }
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockRemoveAllBlocks --
+ *
+ * Removes all blocks added by the provided blocker.
+ *
+ * Results:
+ * Returns the number of entries removed from the blocklist.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+unsigned int
+BlockRemoveAllBlocks(const os_blocker_id_t blocker) // IN: blocker to remove blocks for
+{
+ struct DblLnkLst_Links *curr;
+ struct DblLnkLst_Links *tmp;
+ unsigned int removed = 0;
+
+ os_write_lock(&blockedFilesLock);
+
+ DblLnkLst_ForEachSafe(curr, tmp, &blockedFiles) {
+ BlockInfo *currBlock = DblLnkLst_Container(curr, BlockInfo, links);
+ if (currBlock->blocker == blocker || blocker == OS_UNKNOWN_BLOCKER) {
+
+ DblLnkLst_Unlink1(&currBlock->links);
+
+ /*
+ * We count only entries removed from the -list-, regardless of whether
+ * or not other waiters exist.
+ */
+ ++removed;
+
+ /*
+ * BlockInfos, as the result of placing a block on a file or directory,
+ * reference themselves. When the block is lifted, we need to remove
+ * this self-reference and handle the result appropriately.
+ */
+ if (os_atomic_dec_and_test(&currBlock->refcount)) {
+ /* Free blocks without any waiters ... */
+ LOG(4, "Freeing block with no waiters for blocker [%p] (%s)\n",
+ blocker, currBlock->filename);
+ FreeBlock(blockInfoCache, currBlock);
+ } else {
+ /* ... or wakeup the waiting threads */
+ LOG(4, "Completing block for blocker [%p] (%s)\n",
+ blocker, currBlock->filename);
+ os_complete_all(&currBlock->completion);
+ }
+ }
+ }
+
+ os_write_unlock(&blockedFilesLock);
+
+ return removed;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockWaitOnFile --
+ *
+ * Searches for a block on the provided filename. If one exists, this
+ * function does not return until that block has been lifted; otherwise, it
+ * returns right away.
+ *
+ * Results:
+ * Zero on success, otherwise an appropriate system error if our sleep/
+ * block is interrupted.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+BlockWaitOnFile(const char *filename, // IN: file to block on
+ BlockHandle cookie) // IN: previously found block
+{
+ BlockInfo *block = NULL;
+ int error = 0;
+
+ ASSERT(filename);
+
+ /*
+ * Caller may have used BlockLookup to conditionally search for a
+ * block before actually going to sleep. (This allows the caller to
+ * do a little housekeeping, such as releasing vnode locks, before
+ * blocking here.)
+ */
+ if (cookie == NULL) {
+ os_read_lock(&blockedFilesLock);
+ block = GetBlock(filename, OS_UNKNOWN_BLOCKER);
+ os_read_unlock(&blockedFilesLock);
+
+ if (!block) {
+ /* This file is not blocked, just return */
+ return 0;
+ }
+ } else {
+ /*
+ * Note that the "cookie's" reference count was incremented when it
+ * was fetched via BlockLookup, so this is completely safe. (We'll
+ * decrement it below.)
+ */
+ block = cookie;
+ }
+
+ LOG(4, "(%"OS_FMTTID") Waiting for completion on [%s]\n", os_threadid, filename);
+ error = os_wait_for_completion(&block->completion);
+ LOG(4, "(%"OS_FMTTID") Wokeup from block on [%s]\n", os_threadid, filename);
+
+ /*
+ * The assumptions here are as follows:
+ * 1. The BlockInfo holds a reference to itself. (BlockInfo's refcount
+ * is initialized to 1.)
+ * 2. BlockInfo's self reference is deleted only when BlockInfo is
+ * /also/ removed removed from the block list.
+ *
+ * Therefore, if the reference count hits zero, it's because the block is
+ * no longer in the list, and there is no chance of another thread finding
+ * and referencing this block between our dec_and_test and freeing it.
+ */
+ if (os_atomic_dec_and_test(&block->refcount)) {
+ /* We were the last thread, so clean up */
+ LOG(4, "(%"OS_FMTTID") I am the last to wakeup, freeing the block on [%s]\n",
+ os_threadid, filename);
+ FreeBlock(blockInfoCache, block);
+ }
+
+ return error;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BlockLookup --
+ *
+ * VFS-exported function for searching for blocks.
+ *
+ * Results:
+ * Opaque pointer to a blockInfo if a block is found, NULL otherwise.
+ *
+ * Side effects:
+ * Located blockInfo, if any, has an incremented reference count.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+BlockHandle
+BlockLookup(const char *filename, // IN: pathname to test for
+ // blocking
+ const os_blocker_id_t blocker) // IN: specific blocker to
+ // search for
+{
+ BlockInfo *block;
+
+ os_read_lock(&blockedFilesLock);
+
+ block = GetBlock(filename, blocker);
+
+ os_read_unlock(&blockedFilesLock);
+
+ return block;
+}
+
+
+#ifdef VMX86_DEVEL
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockListFileBlocks --
+ *
+ * Lists all the current file blocks.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+BlockListFileBlocks(void)
+{
+ DblLnkLst_Links *curr;
+ int count = 0;
+
+ os_read_lock(&blockedFilesLock);
+
+ DblLnkLst_ForEach(curr, &blockedFiles) {
+ BlockInfo *currBlock = DblLnkLst_Container(curr, BlockInfo, links);
+ LOG(1, "BlockListFileBlocks: (%d) Filename: [%s], Blocker: [%p]\n",
+ count++, currBlock->filename, currBlock->blocker);
+ }
+
+ os_read_unlock(&blockedFilesLock);
+
+ if (!count) {
+ LOG(1, "BlockListFileBlocks: No blocks currently exist.\n");
+ }
+}
+#endif
+
+
+/* Utility functions */
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * BlockExists --
+ *
+ * Checks if a block already exists for the provided filename.
+ *
+ * Note that this assumes the proper locking has been done on the data
+ * structure holding the blocked files (including ensuring the atomic_dec()
+ * without a kmem_cache_free() is safe).
+ *
+ * Results:
+ * TRUE if a block exists, FALSE otherwise.
+ *
+ * Side effects:
+ * If a block exists, its refcount is incremented and decremented.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static Bool
+BlockExists(const char *filename)
+{
+ BlockInfo *block = GetBlock(filename, OS_UNKNOWN_BLOCKER);
+
+ if (block) {
+ os_atomic_dec(&block->refcount);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * GetBlock --
+ *
+ * Searches for a block on the provided filename by the provided blocker.
+ * If blocker is NULL, it is ignored and any matching filename is returned.
+ * If a block is found, the refcount is incremented.
+ *
+ * Note that this assumes the proper locking has been done on the data
+ * structure holding the blocked files.
+ *
+ * Results:
+ * A pointer to the corresponding BlockInfo if found, NULL otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static BlockInfo *
+GetBlock(const char *filename, // IN: file to find block for
+ const os_blocker_id_t blocker) // IN: blocker associated with this block
+{
+ struct DblLnkLst_Links *curr;
+
+ /*
+ * On FreeBSD we have a mechanism to assert (but not simply check)
+ * that a lock is held. Since semantic is different (panic that
+ * happens if assertion fails can not be suppressed) we are using
+ * different name.
+ */
+#ifdef os_assert_rwlock_held
+ os_assert_rwlock_held(&blockedFilesLock);
+#else
+ ASSERT(os_rwlock_held(&blockedFilesLock));
+#endif
+
+ DblLnkLst_ForEach(curr, &blockedFiles) {
+ BlockInfo *currBlock = DblLnkLst_Container(curr, BlockInfo, links);
+ if ((blocker == OS_UNKNOWN_BLOCKER || currBlock->blocker == blocker) &&
+ strcmp(currBlock->filename, filename) == 0) {
+ os_atomic_inc(&currBlock->refcount);
+ return currBlock;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * AllocBlock --
+ *
+ * Allocates and initializes a new block structure.
+ *
+ * Results:
+ * Pointer to the struct on success, NULL on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+BlockInfo *
+AllocBlock(os_kmem_cache_t *cache, // IN: cache to allocate from
+ const char *filename, // IN: filname of block
+ const os_blocker_id_t blocker) // IN: blocker id
+{
+ BlockInfo *block;
+ size_t ret;
+
+ /* Initialize this file's block structure. */
+ block = os_kmem_cache_alloc(blockInfoCache);
+ if (!block) {
+ return NULL;
+ }
+
+ ret = strlcpy(block->filename, filename, sizeof block->filename);
+ if (ret >= sizeof block->filename) {
+ Warning("BlockAddFileBlock: filename is too large\n");
+ os_kmem_cache_free(blockInfoCache, block);
+ return NULL;
+ }
+
+ DblLnkLst_Init(&block->links);
+ os_atomic_set(&block->refcount, 1);
+ os_completion_init(&block->completion);
+ block->blocker = blocker;
+
+ return block;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * FreeBlock --
+ *
+ * Frees the provided block structure.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+FreeBlock(os_kmem_cache_t *cache, // IN: cache block was allocated from
+ BlockInfo *block) // IN: block to free
+{
+ ASSERT(cache);
+ ASSERT(block);
+
+ os_completion_destroy(&block->completion);
+ os_kmem_cache_free(cache, block);
+}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * block.h --
+ *
+ * Blocking operations for the vmblock driver.
+ */
+
+#ifndef __BLOCK_H__
+#define __BLOCK_H__
+
+#include "os.h"
+
+typedef struct BlockInfo * BlockHandle;
+
+/*
+ * Global functions
+ */
+
+int BlockInit(void);
+void BlockCleanup(void);
+int BlockAddFileBlock(const char *filename, const os_blocker_id_t blocker);
+int BlockRemoveFileBlock(const char *filename, const os_blocker_id_t blocker);
+unsigned int BlockRemoveAllBlocks(const os_blocker_id_t blocker);
+int BlockWaitOnFile(const char *filename, BlockHandle cookie);
+BlockHandle BlockLookup(const char *filename, const os_blocker_id_t blocker);
+#ifdef VMX86_DEVEL
+void BlockListFileBlocks(void);
+#endif
+
+#endif /* __BLOCK_H__ */
--- /dev/null
+/*********************************************************
+ * Copyright (C) 1998 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+#include "vmware.h"
+#include "dbllnklst.h"
+
+/*
+ * dbllnklst.c --
+ *
+ * Light (but nonetheless powerful) implementation of doubly linked lists
+ */
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DblLnkLst_Init --
+ *
+ * Initialize a member of a doubly linked list
+ *
+ * Result
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DblLnkLst_Init(DblLnkLst_Links *l) // IN
+{
+ ASSERT(l);
+
+ l->prev = l->next = l;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DblLnkLst_Link --
+ *
+ * Merge two doubly linked lists into one
+ *
+ * The operation is commutative
+ * The operation is inversible (its inverse is DblLnkLst_Unlink)
+ *
+ * Result
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DblLnkLst_Link(DblLnkLst_Links *l1, // IN
+ DblLnkLst_Links *l2) // IN
+{
+ DblLnkLst_Links *tmp;
+
+ ASSERT(l1);
+ ASSERT(l2);
+
+ (tmp = l1->prev)->next = l2;
+ (l1->prev = l2->prev)->next = l1;
+ l2->prev = tmp ;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DblLnkLst_Unlink --
+ *
+ * Split one doubly linked list into two
+ *
+ * No check is performed: the caller must ensure that both members
+ * belong to the same doubly linked list
+ *
+ * The operation is commutative
+ * The operation is inversible (its inverse is DblLnkLst_Link)
+ *
+ * Result
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DblLnkLst_Unlink(DblLnkLst_Links *l1, // IN
+ DblLnkLst_Links *l2) // IN
+{
+ DblLnkLst_Links *tmp;
+
+ ASSERT(l1);
+ ASSERT(l2);
+
+ tmp = l1->prev ;
+ (l1->prev = l2->prev)->next = l1;
+ (l2->prev = tmp )->next = l2;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DblLnkLst_Unlink1 --
+ *
+ * Unlink an element from its list.
+ *
+ * Result
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DblLnkLst_Unlink1(DblLnkLst_Links *l) // IN
+{
+ ASSERT(l);
+
+ DblLnkLst_Unlink(l, l->next);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * DblLnkLst_IsLinked --
+ *
+ * Determines whether an element is linked with any other elements.
+ *
+ * Results:
+ * TRUE if link is linked, FALSE otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+Bool
+DblLnkLst_IsLinked(DblLnkLst_Links const *l) // IN
+{
+ ASSERT(l);
+
+ ASSERT((l->prev == l && l->next == l) ||
+ (l->prev != l && l->next != l));
+
+ /*
+ * A DblLnkLst_Links is either linked to itself (not linked) or linked to
+ * other elements in a list (linked).
+ */
+ return l->prev != l;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DblLnkLst_LinkFirst --
+ *
+ * Insert 'l' at the beginning of the list anchored at 'head'
+ *
+ * Result
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DblLnkLst_LinkFirst(DblLnkLst_Links *head, // IN
+ DblLnkLst_Links *l) // IN
+{
+ ASSERT(head);
+ ASSERT(l);
+
+ DblLnkLst_Link(head->next, l);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DblLnkLst_LinkLast --
+ *
+ * Insert 'l' at the end of the list anchored at 'head'
+ *
+ * Result
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+DblLnkLst_LinkLast(DblLnkLst_Links *head, // IN
+ DblLnkLst_Links *l) // IN
+{
+ ASSERT(head);
+ ASSERT(l);
+
+ DblLnkLst_Link(head, l);
+}
+
+
+#if 0
+/*
+ * Test code (which also demonstrates how to use this library)
+ */
+
+/*
+ * Add the double linked list capability to any of your data structure just by
+ * adding a DblLnkLst_Links field inside it. It is not required that the field
+ * comes first, but if it does, the execution will be slighly faster.
+ *
+ * Here we create a doubly linked list of integers
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef struct member {
+ int i;
+ DblLnkLst_Links l;
+} member;
+
+
+/* Member constructor */
+member *
+make_member(int i)
+{
+ member *m;
+
+ m = malloc(sizeof(*m));
+ DblLnkLst_Init(&m->l);
+ m->i = i;
+
+ return m;
+}
+
+
+/* Dump a circular list */
+void
+dump_circular(const member *c) // IN
+{
+ const member *current;
+
+ printf("forward: ");
+ current = c;
+ do {
+ printf("%d ", current->i);
+ current = DblLnkLst_Container(current->l.next, member, l);
+ } while (current != c);
+ printf("backward: ");
+ do {
+ printf("%d ", current->i);
+ current = DblLnkLst_Container(current->l.prev, member, l);
+ } while (current != c);
+ printf("\n");
+}
+
+
+/* Dump an anchored list */
+void
+dump_anchored(const DblLnkLst_Links *h) // IN
+{
+ DblLnkLst_Links *cur_l;
+
+ printf("forward: ");
+ for (cur_l = h->next; cur_l != h; cur_l = cur_l->next) {
+ member *current;
+
+ current = DblLnkLst_Container(cur_l, member, l);
+ printf("%d ", current->i);
+ }
+ printf("backward: ");
+ for (cur_l = h->prev; cur_l != h; cur_l = cur_l->prev) {
+ member *current;
+
+ current = DblLnkLst_Container(cur_l, member, l);
+ printf("%d ", current->i);
+ }
+ printf("\n");
+}
+
+
+/* Test code entry point */
+int
+main(int argc, // IN
+ char **argv) // IN
+{
+ member *c1;
+ member *c2;
+ member *c3;
+ member *c4;
+
+ DblLnkLst_Links h;
+ member *a1;
+ member *a2;
+ member *a3;
+
+ printf("Circular list: there is no origin\n");
+
+ /* Create the 1st member */
+ c1 = make_member(1);
+ /* Special case: there is no list to merge with, initially */
+
+ /* Add the 2nd member _after_ the 1st one */
+ c2 = make_member(2);
+ DblLnkLst_Link(&c1->l, &c2->l);
+
+ /* Add the 3rd member _after_ the 2nd one */
+ c3 = make_member(3);
+ DblLnkLst_Link(&c1->l, &c3->l);
+
+ /* Add the 4th member _before_ the 3rd one */
+ c4 = make_member(4);
+ DblLnkLst_Link(&c3->l, &c4->l);
+
+ printf("See it from this member...\n");
+ dump_circular(c1);
+ printf("...Or from this one\n");
+ dump_circular(c4);
+
+ printf("\n");
+ printf("Anchored (linear) list: it has a beginning and an end\n");
+
+ /* Create the 'head' of the list */
+ DblLnkLst_Init(&h);
+
+ /* Add the 1st member at the _end_ */
+ a1 = make_member(5);
+ DblLnkLst_LinkLast(&h, &a1->l);
+
+ /* Add the 2nd member at the _beginning_ */
+ a2 = make_member(6);
+ DblLnkLst_LinkFirst(&h, &a2->l);
+
+ /* Add the 3rd member _before_ the 1st one */
+ a3 = make_member(7);
+ DblLnkLst_Link(&a1->l, &a3->l);
+
+ dump_anchored(&h);
+
+ printf("\n");
+ printf("Merge both lists: the result is an anchored list\n");
+
+ DblLnkLst_Link(&h, &c4->l);
+
+ dump_anchored(&h);
+
+ printf("\n");
+ printf("Remove a member\n");
+
+ DblLnkLst_Unlink1(&c3->l);
+
+ dump_anchored(&h);
+
+ printf("\n");
+ printf("Split the result in two lists: an anchored one and a circular "
+ "one\n");
+ DblLnkLst_Unlink(&h, &a1->l);
+
+ dump_anchored(&h);
+ dump_circular(a1);
+
+ return 0;
+}
+#endif
/*********************************************************
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
/*********************************************************
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+
+/*
+ * module.c --
+ *
+ * Main loading and unloading of kernel module.
+ */
+
+#include <sys/errno.h>
+
+#include "module.h"
+#include "block.h"
+
+static vfsdef_t VMBlockVfsDef = {
+ VFSDEF_VERSION, /* Structure version: defined in <sys/vfs.h> */
+ VMBLOCK_FS_NAME, /* Name of file system */
+ VMBlockInit, /* File system initialization routine */
+ VMBLOCK_VFSSW_FLAGS, /* File system flags */
+ NULL /* No mount options */
+};
+
+/* Filesystem module structure */
+static struct modlfs VMBlockModlfs = {
+ &mod_fsops, /* Module operation structure: for
+ * auto loading/unloading */
+ "VMBlock File system", /* Name */
+ &VMBlockVfsDef /* Filesystem type definition record */
+};
+
+static struct modlinkage VMBlockModlinkage = {
+ MODREV_1, /* Module revision: must be MODREV_1 */
+ {
+ &VMBlockModlfs, /* FS module structure */
+ NULL,
+ }
+};
+
+#ifdef VMX86_DEBUG
+/* XXX: Figure out how to pass this in at module load time. */
+int LOGLEVEL = 4;
+#else
+int LOGLEVEL = 0;
+#endif
+
+int vmblockType;
+vnodeops_t *vmblockVnodeOps;
+
+
+
+
+/*
+ * Module loading/unloading/info functions.
+ */
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * _init --
+ * Invoked when module is being loaded into kernel, and is called before
+ * any function in the module. Any state that spans all instances of the
+ * driver should be allocated and initialized here.
+ *
+ * Results:
+ * Returns the result of mod_install(9F), which is zero on success and a
+ * non-zero value on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+_init(void)
+{
+ int error;
+
+ error = mod_install(&VMBlockModlinkage);
+ if (error) {
+ Warning("Could not install vmblock module.\n");
+ return error;
+ }
+
+ error = BlockInit();
+ if (error) {
+ Warning("Could not initialize blocking.\n");
+ mod_remove(&VMBlockModlinkage);
+ return error;
+ }
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * _fini --
+ * Invoked when a module is being removed from the kernel.
+ *
+ * Results:
+ * Returns the result of mod_remove(9F), which is zero on success, and a
+ * non-zero value on failure.
+ *
+ * Side effects:
+ * The module will be removed from the kernel.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+_fini(void)
+{
+ int error;
+
+ error = mod_remove(&VMBlockModlinkage);
+ if (error) {
+ Warning("Could not remove vmblock module.\n");
+ return error;
+ }
+
+ BlockCleanup();
+ vfs_freevfsops_by_type(vmblockType);
+ vn_freevnodeops(vmblockVnodeOps);
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * _info --
+ *
+ * Invoked when the modinfo(1M) command is executed. mod_info(9F) handles
+ * this for us.
+ *
+ * Results:
+ * Returns mod_info(9F)'s results, which are a non-zero value on success, and
+ * zero on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+_info(struct modinfo *modinfop) // OUT: Filled in with module's information
+{
+ return mod_info(&VMBlockModlinkage, modinfop);
+}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+
+/*
+ * module.h --
+ *
+ * Defnitions for entire vmblock module.
+ */
+
+#ifndef __MODULE_H_
+#define __MODULE_H_
+
+#include <sys/vfs.h>
+#include <sys/vnode.h>
+#include <sys/pathname.h>
+#include <sys/cmn_err.h>
+#include <sys/modctl.h>
+#include <sys/param.h>
+
+#if SOL11
+#include <sys/vfs_opreg.h> /* fs_operation_def_t, ... */
+#endif
+
+#include "vm_basic_types.h"
+
+/*
+ * Macros
+ */
+#define VMBLOCK_FS_NAME "vmblock"
+#define VMBLOCK_VFS_FLAGS 0
+#define VMBLOCK_VFSSW_FLAGS 0
+#define VFSPTOMIP(vfsp) ((VMBlockMountInfo *)(vfsp)->vfs_data)
+#define VPTOMIP(vp) VFSPTOMIP((vp)->v_vfsp)
+#define VPTOVIP(vp) ((VMBlockVnodeInfo *)(vp)->v_data)
+
+/*
+ * Debug logging
+ */
+#define VMBLOCK_DEBUG CE_WARN
+#define VMBLOCK_ERROR CE_WARN
+#define VMBLOCK_ENTRY_LOGLEVEL 7
+#undef ASSERT
+#ifdef VMX86_DEVEL
+# define Debug(level, fmt, args...) level > LOGLEVEL ? \
+ 0 : \
+ cmn_err(VMBLOCK_DEBUG, fmt, ##args)
+# define LOG(level, fmt, args...) Debug(level, fmt, ##args)
+# define ASSERT(expr) (expr) ? \
+ 0 : \
+ cmn_err(CE_PANIC, "ASSERT: %s:%d\n", \
+ __FILE__, __LINE__)
+#else
+# define Debug(level, fmt, args...)
+# define LOG(level, fmt, args...)
+# define ASSERT(expr)
+#endif
+#define Warning(fmt, args...) cmn_err(VMBLOCK_ERROR, fmt, ##args)
+
+#if defined(SOL9)
+# define OS_VFS_VERSION 2
+#elif defined(SOL10)
+# define OS_VFS_VERSION 3
+#elif defined(SOL11)
+# define OS_VFS_VERSION 5
+#else
+# error "Unknown Solaris version, can't set OS_VFS_VERSION"
+#endif
+
+
+
+#if OS_VFS_VERSION <= 3
+# define VMBLOCK_VOP(vopName, vopFn, vmblkFn) { vopName, vmblkFn }
+#else
+# define VMBLOCK_VOP(vopName, vopFn, vmblkFn) { vopName, { .vopFn = vmblkFn } }
+#endif
+
+/*
+ * Types
+ */
+typedef struct VMBlockMountInfo {
+ struct vnode *root;
+ struct vnode *redirectVnode;
+ struct pathname redirectPath;
+} VMBlockMountInfo;
+
+typedef struct VMBlockVnodeInfo {
+ struct vnode *realVnode;
+ char name[MAXNAMELEN];
+ size_t nameLen;
+} VMBlockVnodeInfo;
+
+
+/*
+ * Externs
+ */
+
+/* Filesystem initialization routine (see vnops.c) */
+EXTERN int VMBlockInit(int, char *);
+
+/* Needed in struct modlfs */
+EXTERN struct mod_ops mod_fsops;
+
+EXTERN const fs_operation_def_t vnodeOpsArr[];
+EXTERN vnodeops_t *vmblockVnodeOps;
+EXTERN int vmblockType;
+
+EXTERN int LOGLEVEL;
+
+#endif /* __MODULE_H_ */
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+
+/*
+ * os.h --
+ *
+ * OS-specific definitions.
+ */
+
+
+#ifndef __OS_H__
+#define __OS_H__
+
+#include <sys/types.h>
+#include <sys/kmem.h>
+#include <sys/ksynch.h>
+#include <sys/atomic.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+#include <sys/cmn_err.h>
+#include <sys/varargs.h>
+#include <sys/sunddi.h>
+
+#include "vm_basic_types.h"
+
+typedef krwlock_t os_rwlock_t;
+typedef kmem_cache_t os_kmem_cache_t;
+typedef struct os_completion_t {
+ Bool completed;
+ kmutex_t mutex;
+ kcondvar_t cv;
+} os_completion_t;
+/*
+ * Changing the os_atomic_t type requires that the os_atomic_* macros below be
+ * changed as well.
+ */
+typedef uint_t os_atomic_t;
+typedef kthread_t * os_blocker_id_t;
+
+#define OS_UNKNOWN_BLOCKER NULL
+#define OS_ENOMEM ENOMEM
+#define OS_ENOENT ENOENT
+#define OS_EEXIST EEXIST
+#define OS_PATH_MAX MAXPATHLEN
+#define OS_KMEM_CACHE_FLAG_HWALIGN 0
+
+#define OS_FMTTID "lu"
+#define os_threadid (uintptr_t)curthread
+
+#define os_panic(fmt, args) vcmn_err(CE_PANIC, fmt, args)
+
+#define os_rwlock_init(lock) rw_init(lock, NULL, RW_DRIVER, NULL)
+#define os_rwlock_destroy(lock) rw_destroy(lock)
+/*
+ * rw_lock_held() returns 1 if the lock is read locked, and rw_owner() returns
+ * the current lock owner if it's write locked. In the read locked case, we
+ * just have to assume we're one of the readers.
+ */
+#define os_rwlock_held(lock) (rw_lock_held(lock) || \
+ rw_owner(lock) == curthread)
+#define os_read_lock(lock) rw_enter(lock, RW_READER)
+#define os_write_lock(lock) rw_enter(lock, RW_WRITER)
+#define os_read_unlock(lock) rw_exit(lock)
+#define os_write_unlock(lock) rw_exit(lock)
+
+#define os_kmem_cache_create(name, size, align, ctor) \
+ kmem_cache_create(name, size, align, ctor, NULL, NULL, NULL, NULL, 0)
+#define os_kmem_cache_destroy(cache) kmem_cache_destroy(cache)
+#define os_kmem_cache_alloc(cache) kmem_cache_alloc(cache, KM_SLEEP)
+#define os_kmem_cache_free(cache, elem) kmem_cache_free(cache, elem)
+
+#define os_completion_init(comp) \
+ do { \
+ (comp)->completed = FALSE; \
+ mutex_init(&(comp)->mutex, NULL, MUTEX_DRIVER, NULL); \
+ cv_init(&(comp)->cv, NULL, CV_DRIVER, NULL); \
+ } while (0)
+#define os_completion_destroy(comp) \
+ do { \
+ mutex_destroy(&(comp)->mutex); \
+ cv_destroy(&(comp)->cv); \
+ } while (0)
+/*
+ * XXX The following should be made interruptible such as via
+ * cv_wait_sig, and returning that function's return value. In
+ * the meantime, fake "success" by evaluating to 0.
+ */
+#define os_wait_for_completion(comp) \
+({ \
+ mutex_enter(&(comp)->mutex); \
+ while (!(comp)->completed) { \
+ cv_wait(&(comp)->cv, &(comp)->mutex); \
+ } \
+ mutex_exit(&(comp)->mutex); \
+ 0; \
+})
+#define os_complete_all(comp) \
+ do { \
+ mutex_enter(&(comp)->mutex); \
+ (comp)->completed = TRUE; \
+ mutex_exit(&(comp)->mutex); \
+ cv_broadcast(&(comp)->cv); \
+ } while (0)
+
+/* These will need to change if os_atomic_t is changed from uint_t. */
+#define os_atomic_dec_and_test(atomic) (atomic_dec_uint_nv(atomic) == 0)
+#define os_atomic_dec(atomic) atomic_dec_uint(atomic)
+#define os_atomic_set(atomic, val) atomic_swap_uint(atomic, val)
+#define os_atomic_inc(atomic) atomic_inc_uint(atomic)
+#define os_atomic_read(atomic) atomic_add_int_nv(atomic, 0)
+
+#endif /* __OS_H__ */
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+
+/*
+ * stubs.c --
+ *
+ * Common stubs.
+ */
+
+#include <stdarg.h>
+
+#include "os.h"
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * Panic --
+ *
+ * Panic implementation.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+Panic(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ os_panic(fmt, args);
+ va_end(args);
+}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+
+/*
+ * stubs.h --
+ *
+ */
+
+
+#ifndef __STUBS_H__
+#define __STUBS_H__
+
+#if defined(linux) && !defined(vmblock_fuse)
+# include "driver-config.h"
+# include "compat_version.h"
+#endif
+
+void Panic(const char *fmt, ...);
+
+#endif /* __STUBS_H__ */
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+
+/*
+ * vfsops.c --
+ *
+ * VFS operations for vmblock file system.
+ */
+
+#include <sys/types.h>
+#include <sys/kmem.h> /* kmem_zalloc() */
+#include <sys/errno.h> /* error codes */
+#include <sys/mount.h> /* MS_OVERLAY */
+#include <sys/sysmacros.h> /* makedevice macro */
+#include <sys/systm.h> /* cmpldev() */
+#include <sys/policy.h> /* secpolicy_fs_mount() */
+
+#include "module.h"
+
+
+/*
+ * Variables
+ */
+vfsops_t *vmblockVfsOps;
+
+static major_t vmblockMajor;
+static minor_t vmblockMinor;
+static kmutex_t vmblockMutex;
+
+
+/*
+ * Prototypes
+ */
+int VMBlockVnodeGet(struct vnode **vpp, struct vnode *realVp,
+ const char *name, size_t nameLen,
+ struct vnode *dvp, struct vfs *vfsp, Bool isRoot);
+int VMBlockVnodePut(struct vnode *vp);
+static int VMBlockMount(struct vfs *vfsp, struct vnode *vnodep,
+ struct mounta *mntp, struct cred *credp);
+static int VMBlockUnmount(struct vfs *vfsp, int mflag, struct cred *credp);
+static int VMBlockRoot(struct vfs *vfsp, struct vnode **vnodepp);
+static int VMBlockStatvfs(struct vfs *vfsp, struct statvfs64 *stats);
+
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockVnodeGet --
+ *
+ * Creates a vnode.
+ *
+ * Note that realVp is assumed to be held (see the comment in the function
+ * for further explanation).
+ *
+ * Results:
+ * Returns zero on success and a non-zero error code on failure. On
+ * success, vpp is filled in with a new, held vnode.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+VMBlockVnodeGet(struct vnode **vpp, // OUT: Filled with address of new vnode
+ struct vnode *realVp, // IN: Real vnode (assumed held)
+ const char *name, // IN: Relative name of the file
+ size_t nameLen, // IN: Size of name
+ struct vnode *dvp, // IN: Parent directory's vnode
+ struct vfs *vfsp, // IN: Filesystem structure
+ Bool isRoot) // IN: If is root directory of fs
+{
+ VMBlockVnodeInfo *vip;
+ struct vnode *vp;
+ char *curr;
+ int ret;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockVnodeGet: entry\n");
+
+ ASSERT(vpp);
+ ASSERT(realVp);
+ ASSERT(vfsp);
+ ASSERT(name);
+ ASSERT(dvp || isRoot);
+
+ vp = vn_alloc(KM_SLEEP);
+ if (!vp) {
+ return ENOMEM;
+ }
+
+ vip = kmem_zalloc(sizeof *vip, KM_SLEEP);
+ vp->v_data = (void *)vip;
+
+ /*
+ * Store the path that this file redirects to. For the root vnode we just
+ * store the provided path, but for all others we first copy in the parent
+ * directory's path.
+ */
+ curr = vip->name;
+
+ if (!isRoot) {
+ VMBlockVnodeInfo *dvip = VPTOVIP(dvp);
+ if (dvip->nameLen + 1 + nameLen + 1 >= sizeof vip->name) {
+ ret = ENAMETOOLONG;
+ goto error;
+ }
+
+ memcpy(vip->name, dvip->name, dvip->nameLen);
+ vip->name[dvip->nameLen] = '/';
+ curr = vip->name + dvip->nameLen + 1;
+ }
+
+ if (nameLen + 1 > (sizeof vip->name - (curr - vip->name))) {
+ ret = ENAMETOOLONG;
+ goto error;
+ }
+
+ memcpy(curr, name, nameLen);
+ curr[nameLen] = '\0';
+ vip->nameLen = nameLen + (curr - vip->name);
+
+ /*
+ * We require the caller to have held realVp so we don't need VN_HOLD() it
+ * here here even though we VN_RELE() this vnode in VMBlockVnodePut().
+ * Despite seeming awkward, this is more natural since the function that our
+ * caller obtained realVp from provided a held vnode.
+ */
+ vip->realVnode = realVp;
+
+ /*
+ * Now we'll initialize the vnode. We need to set the file type, vnode
+ * operations, flags, filesystem pointer, reference count, and device.
+ */
+ /* The root directory is our only directory; the rest are symlinks. */
+ vp->v_type = isRoot ? VDIR : VLNK;
+
+ vn_setops(vp, vmblockVnodeOps);
+
+ vp->v_flag = VNOMAP | VNOMOUNT | VNOSWAP | isRoot ? VROOT : 0;
+ vp->v_vfsp = vfsp;
+ vp->v_rdev = NODEV;
+
+ /* Fill in the provided address with the new vnode. */
+ *vpp = vp;
+
+ return 0;
+
+error:
+ kmem_free(vip, sizeof *vip);
+ vn_free(vp);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockVnodePut --
+ *
+ * Frees state associated with provided vnode.
+ *
+ * Results:
+ * Zero on success, non-zero error code on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+VMBlockVnodePut(struct vnode *vp)
+{
+ VMBlockVnodeInfo *vip;
+ struct vnode *realVnode;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockVnodePut: entry (%p)\n", vp);
+
+ mutex_enter(&vp->v_lock);
+ if (vp->v_count > 1) {
+ vp->v_count--;
+ mutex_exit(&vp->v_lock);
+ return 0;
+ }
+ mutex_exit(&vp->v_lock);
+
+ vip = (VMBlockVnodeInfo *)vp->v_data;
+ realVnode = vip->realVnode;
+
+ kmem_free(vip, sizeof *vip);
+ vn_free(vp);
+ /*
+ * VMBlockVnodeGet() doesn't VN_HOLD() the real vnode, but all callers of it
+ * will have the vnode held, so we need to VN_RELE() here.
+ */
+ VN_RELE(realVnode);
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockInit --
+ *
+ * This is the file system initialization routine. It creates an array of
+ * fs_operation_def_t for all the vfs operations, then calls vfs_makefsops()
+ * and vfs_setfsops() to assign them to the file system properly.
+ *
+ * Results:
+ * Returns zero on success and a non-zero error code on error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+VMBlockInit(int fstype, // IN: file system type
+ char *name) // IN: Name of the file system
+{
+ int ret;
+ static const fs_operation_def_t vfsOpsArr[] = {
+ VMBLOCK_VOP(VFSNAME_MOUNT, vfs_mount, VMBlockMount),
+ VMBLOCK_VOP(VFSNAME_UNMOUNT, vfs_unmount, VMBlockUnmount),
+ VMBLOCK_VOP(VFSNAME_ROOT, vfs_root, VMBlockRoot),
+ VMBLOCK_VOP(VFSNAME_STATVFS, vfs_statvfs, VMBlockStatvfs),
+ { NULL }
+ };
+
+ if (!name) {
+ Warning("VMBlockInit: received NULL input from kernel.\n");
+ return EINVAL;
+ }
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockInit: fstype=%d, name=\"%s\"\n", fstype, name);
+
+ /*
+ * Set our file system type and the vfs operations in the kernel's VFS
+ * switch table.
+ */
+ vmblockType = fstype;
+
+ ret = vfs_setfsops(vmblockType, vfsOpsArr, &vmblockVfsOps);
+ if (ret) {
+ Warning("VMBlockInit: could not set vfs operations.\n");
+ return ret;
+ }
+
+ ret = vn_make_ops(name, vnodeOpsArr, &vmblockVnodeOps);
+ if (ret) {
+ Warning("VMBlockInit: could not create vnode operations.\n");
+ /*
+ * It's important not to call vfs_freevfsops() here; that's only for
+ * freeing ops created with vfs_makefsops().
+ */
+ vfs_freevfsops_by_type(vmblockType);
+ return ret;
+ }
+
+ /*
+ * We need to find a unique device number for this instance of the module;
+ * it will be used at each mount to secure a unique device number and file
+ * system identifier. If one cannot be located, we'll just use zero like
+ * other Solaris file systems.
+ */
+ if ((vmblockMajor = getudev()) == (major_t)-1) {
+ Warning("VMBlockInit: could not obtain unique device.\n");
+ vmblockMajor = 0;
+ }
+ vmblockMinor = 0;
+ mutex_init(&vmblockMutex, NULL, MUTEX_DEFAULT, NULL);
+
+ return 0;
+}
+
+
+/*
+ * VFS Entry Points
+ */
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockMount --
+ *
+ * This function is invoked when mount(2) is called on our file system.
+ * The file system is mounted on the supplied vnode.
+ *
+ * Results:
+ * Returns zero on success and an appropriate error code on error.
+ *
+ * Side effects:
+ * The file system is mounted on top of vnodep.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockMount(struct vfs *vfsp, // IN: file system to mount
+ struct vnode *vnodep, // IN: Vnode that we are mounting on
+ struct mounta *mntp, // IN: Arguments to mount(2) from user
+ struct cred *credp) // IN: Credentials of caller
+{
+ VMBlockMountInfo *mip;
+ int ret;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockMount: entry\n");
+
+ /*
+ * These next few checks are done by all other Solaris file systems, so
+ * let's follow their lead.
+ */
+ ret = secpolicy_fs_mount(credp, vnodep, vfsp);
+ if (ret) {
+ Warning("VMBlockMount: mounting security check failed.\n");
+ return ret;
+ }
+
+ if (vnodep->v_type != VDIR) {
+ Warning("VMBlockMount: not mounting on a directory.\n");
+ return ENOTDIR;
+ }
+
+ mutex_enter(&vnodep->v_lock);
+ if ((mntp->flags & MS_OVERLAY) == 0 &&
+ (vnodep->v_count != 1 || (vnodep->v_flag & VROOT))) {
+ mutex_exit(&vnodep->v_lock);
+ Warning("VMBlockMount: cannot allow unrequested overlay mount.\n");
+ return EBUSY;
+ }
+ mutex_exit(&vnodep->v_lock);
+
+ /*
+ * The directory we are redirecting to is specified as the special file
+ * since we have no actual device to mount on. We store that path in the
+ * mount information structure (note that there's another allocation inside
+ * pn_get() so we must pn_free() that path at unmount time). KM_SLEEP
+ * guarantees our memory allocation will succeed (pn_get() uses this flag
+ * too).
+ */
+ mip = kmem_zalloc(sizeof *mip, KM_SLEEP);
+ ret = pn_get(mntp->spec,
+ (mntp->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE,
+ &mip->redirectPath);
+ if (ret) {
+ Warning("VMBlockMount: could not obtain redirecting directory.\n");
+ kmem_free(mip, sizeof *mip);
+ return ret;
+ }
+
+ /* Do a lookup on the specified path. */
+ ret = lookupname(mntp->spec,
+ (mntp->flags & MS_SYSSPACE) ? UIO_SYSSPACE : UIO_USERSPACE,
+ FOLLOW,
+ NULLVPP,
+ &mip->redirectVnode);
+ if (ret) {
+ Warning("VMBlockMount: could not obtain redirecting directory.\n");
+ goto error_lookup;
+ }
+
+ if (mip->redirectVnode->v_type != VDIR) {
+ Warning("VMBlockMount: not redirecting to a directory.\n");
+ ret = ENOTDIR;
+ goto error;
+ }
+
+ /*
+ * Initialize our vfs structure.
+ */
+ vfsp->vfs_vnodecovered = vnodep;
+ vfsp->vfs_flag &= ~VFS_UNMOUNTED;
+ vfsp->vfs_flag |= VMBLOCK_VFS_FLAGS;
+ vfsp->vfs_bsize = PAGESIZE;
+ vfsp->vfs_fstype = vmblockType;
+ vfsp->vfs_bcount = 0;
+ /* If we had mount options, we'd call vfs_setmntopt with vfsp->vfs_mntopts */
+
+ /* Locate a unique device minor number for this mount. */
+ mutex_enter(&vmblockMutex);
+ do {
+ vfsp->vfs_dev = makedevice(vmblockMajor, vmblockMinor);
+ vmblockMinor = (vmblockMinor + 1) & L_MAXMIN32;
+ } while (vfs_devismounted(vfsp->vfs_dev));
+ mutex_exit(&vmblockMutex);
+
+ vfs_make_fsid(&vfsp->vfs_fsid, vfsp->vfs_dev, vmblockType);
+ vfsp->vfs_data = (caddr_t)mip;
+
+ /*
+ * Now create the root vnode of the file system.
+ */
+ ret = VMBlockVnodeGet(&mip->root, mip->redirectVnode,
+ mip->redirectPath.pn_path,
+ mip->redirectPath.pn_pathlen,
+ NULL, vfsp, TRUE);
+ if (ret) {
+ Warning("VMBlockMount: couldn't create root vnode.\n");
+ ret = EFAULT;
+ goto error;
+ }
+
+ VN_HOLD(vfsp->vfs_vnodecovered);
+ return 0;
+
+error:
+ /* lookupname() provides a held vnode. */
+ VN_RELE(mip->redirectVnode);
+error_lookup:
+ pn_free(&mip->redirectPath);
+ kmem_free(mip, sizeof *mip);
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockUnmount --
+ *
+ * This function is invoked when umount(2) is called on our file system.
+ *
+ * Results:
+ * Returns zero on success and an error code on error.
+ *
+ * Side effects:
+ * The root vnode will be freed.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockUnmount(struct vfs *vfsp, // IN: This file system
+ int flag, // IN: Unmount flags
+ struct cred *credp) // IN: Credentials of caller
+{
+ VMBlockMountInfo *mip;
+ int ret;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockUnmount: entry\n");
+
+ ret = secpolicy_fs_unmount(credp, vfsp);
+ if (ret) {
+ return ret;
+ }
+
+ mip = (VMBlockMountInfo *)vfsp->vfs_data;
+
+ mutex_enter(&mip->root->v_lock);
+ if (mip->root->v_count > 1) {
+ mutex_exit(&mip->root->v_lock);
+ return EBUSY;
+ }
+ mutex_exit(&mip->root->v_lock);
+
+ VN_RELE(vfsp->vfs_vnodecovered);
+ /*
+ * We don't need to VN_RELE() mip->redirectVnode since it's the realVnode
+ * for mip->root. That means when we VN_RELE() mip->root and
+ * VMBlockInactive() is called, VMBlockVnodePut() will VN_RELE()
+ * mip->redirectVnode for us. It's like magic, but better.
+ */
+ VN_RELE(mip->root);
+
+ pn_free(&mip->redirectPath);
+ kmem_free(mip, sizeof *mip);
+
+ vfsp->vfs_flag |= VFS_UNMOUNTED;
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockRoot --
+ *
+ * This supplies the root vnode for the file system.
+ *
+ * Results:
+ * Returns zero on success and an error code on error. On success vnodepp
+ * is set to the pointer of the root vnode.
+ *
+ * Side effects:
+ * The root vnode's reference count is incremented by one.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockRoot(struct vfs *vfsp, // IN: file system to find root vnode of
+ struct vnode **vnodepp) // OUT: Set to pointer to root vnode of this fs
+{
+ VMBlockMountInfo *mip;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockRoot: entry\n");
+
+ mip = (VMBlockMountInfo *)vfsp->vfs_data;
+
+ VN_HOLD(mip->root);
+ *vnodepp = mip->root;
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockStatvfs --
+ *
+ * Provides statistics for the provided file system. The values provided
+ * by this function are fake.
+ *
+ * Results:
+ * Returns zero on success and a non-zero error code on exit.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int
+VMBlockStatvfs(struct vfs *vfsp, // IN: file system to get statistics for
+ struct statvfs64 *stats) // OUT: Statistics are placed into this struct
+{
+ dev32_t dev32;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockStatvfs: entry\n");
+
+ /* Clear stats struct, then fill it in with our values. */
+ memset(stats, 0, sizeof *stats);
+
+ /*
+ * Macros in case we need these elsewhere later.
+ *
+ * Since vmblock does not provide any actual storage, we use zero so that
+ * the output of df(1) is pleasant for users.
+ */
+ #define VMBLOCK_BLOCKSIZE PAGESIZE
+ #define VMBLOCK_BLOCKS_TOTAL 0
+ #define VMBLOCK_BLOCKS_FREE 0
+ #define VMBLOCK_BLOCKS_AVAIL 0
+ #define VMBLOCK_FILES_TOTAL 0
+ #define VMBLOCK_FILES_FREE 0
+ #define VMBLOCK_FILES_AVAIL 0
+
+ /* Compress the device number to 32-bits for consistency on 64-bit systems. */
+ cmpldev(&dev32, vfsp->vfs_dev);
+
+ stats->f_bsize = VMBLOCK_BLOCKSIZE; /* Preferred fs block size */
+ stats->f_frsize = VMBLOCK_BLOCKSIZE; /* Fundamental fs block size */
+ /* Next six are u_longlong_t */
+ stats->f_blocks = VMBLOCK_BLOCKS_TOTAL; /* Total blocks on fs */
+ stats->f_bfree = VMBLOCK_BLOCKS_FREE; /* Total free blocks */
+ stats->f_bavail = VMBLOCK_BLOCKS_AVAIL; /* Total blocks avail to non-root */
+ stats->f_files = VMBLOCK_FILES_TOTAL; /* Total files (inodes) */
+ stats->f_ffree = VMBLOCK_FILES_FREE; /* Total files free */
+ stats->f_favail = VMBLOCK_FILES_AVAIL; /* Total files avail to non-root */
+ stats->f_fsid = dev32; /* file system id */
+ stats->f_flag &= ST_NOSUID; /* Flags: we don't support setuid. */
+ stats->f_namemax = MAXNAMELEN; /* Max filename; use Solaris default. */
+
+ /* Memset above and -1 of array size as n below ensure NUL termination. */
+ strncpy(stats->f_basetype, VMBLOCK_FS_NAME, sizeof stats->f_basetype - 1);
+ strncpy(stats->f_fstr, VMBLOCK_FS_NAME, sizeof stats->f_fstr - 1);
+
+ return 0;
+}
/*********************************************************
* Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
/*********************************************************
* Copyright (C) 2003 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
#elif defined(__APPLE__) && defined(KERNEL)
+#include "availabilityMacOS.h"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// The Mac OS 10.5 kernel SDK defines va_copy in stdarg.h.
+#include <stdarg.h>
+#else
/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
+ * The Mac OS 10.4 kernel SDK needs va_copy. Based on inspection of
+ * stdarg.h from the MacOSX10.4u.sdk kernel framework, this should
+ * work.
*/
-
#define va_copy(dest, src) ((dest) = (src))
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#elif defined(__GNUC__) && (__GNUC__ < 3)
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
/*********************************************************
* Copyright (C) 2006-2008 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
# include <sys/param.h>
#endif
-#define VMBLOCK_FS_NAME "vmblock"
+
+/*
+ * FUSE definitions. They are supposed to be used by userspace code and
+ * therefore not guarded by ARCH defines since FUSE can potentially
+ * be used on different operating systems.
+ */
+
+#define VMBLOCK_FUSE_ADD_FILEBLOCK 'a'
+#define VMBLOCK_FUSE_DEL_FILEBLOCK 'd'
+#ifdef VMX86_DEVEL
+# define VMBLOCK_FUSE_LIST_FILEBLOCKS 'l'
+#endif /* VMX86_DEVEL */
+
+/*
+ * If you try 'read'-ing from file descriptor vmblock-fuse is supposed
+ * to respond with the following. It is used to check whether we deal
+ * with FUSE or in-kernel implementation.
+ */
+#define VMBLOCK_FUSE_READ_RESPONSE "I am VMBLOCK-FUSE"
+
+#define VMBLOCK_FUSE_FS_NAME "fuse.vmware-vmblock"
+#define VMBLOCK_FUSE_MOUNT_POINT "/tmp/vmblock-fuse"
+#define VMBLOCK_FUSE_CTRL_MNTPNT "blockdir"
+#define VMBLOCK_FUSE_FS_ROOT VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_CTRL_MNTPNT
+#define VMBLOCK_FUSE_DEVICE_NAME "dev"
+#define VMBLOCK_FUSE_DEVICE VMBLOCK_FUSE_MOUNT_POINT "/" VMBLOCK_FUSE_DEVICE_NAME
+#define VMBLOCK_FUSE_DEVICE_MODE O_RDWR
/* Commands for the control half of vmblock driver */
#if defined(vmblock_fuse)
+/* These definitions are for vmblock-fuse module itself */
# include <unistd.h>
# include <limits.h>
# include <string.h>
# include <errno.h>
# include "vm_basic_types.h"
-# define VMBLOCK_ADD_FILEBLOCK 'a'
-# define VMBLOCK_DEL_FILEBLOCK 'd'
+# define VMBLOCK_ADD_FILEBLOCK VMBLOCK_FUSE_ADD_FILEBLOCK
+# define VMBLOCK_DEL_FILEBLOCK VMBLOCK_FUSE_DEL_FILEBLOCK
# ifdef VMX86_DEVEL
-# define VMBLOCK_LIST_FILEBLOCKS 'l'
+# define VMBLOCK_LIST_FILEBLOCKS VMBLOCK_FUSE_LIST_FILEBLOCKS
# endif /* VMX86_DEVEL */
/*
* Some of the following names don't actually make much sense on their own.
* They're used for consistency with the other ports. See the file header for
* explanations of what they're used for.
*/
-# define VMBLOCK_DEVICE_NAME "dev"
-# define VMBLOCK_CONTROL_MOUNTPOINT "blockdir"
-# define VMBLOCK_DEVICE "/tmp/vmblock/" VMBLOCK_DEVICE_NAME
-# define VMBLOCK_DEVICE_MODE O_WRONLY
-# define VMBLOCK_MOUNT_POINT "/tmp/vmblock/" VMBLOCK_CONTROL_MOUNTPOINT
-static INLINE ssize_t
- VMBLOCK_CONTROL(int fd, char op, const char *path)
-{
- /*
- * buffer needs room for an operation character and a string with max length
- * PATH_MAX - 1.
- */
-
- char buffer[PATH_MAX];
- size_t pathLength;
-
- pathLength = strlen(path);
- if (pathLength >= PATH_MAX) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- buffer[0] = op;
- memcpy(buffer + 1, path, pathLength);
-
- /*
- * The lseek is only to prevent the file pointer from overflowing;
- * vmblock-fuse ignores the file pointer / offset. Overflowing the file
- * pointer causes write to fail:
- * http://article.gmane.org/gmane.comp.file-systems.fuse.devel/6648
- * There's also a race condition here where many threads all calling
- * VMBLOCK_CONTROL at the same time could have all their seeks executed one
- * after the other, followed by all the writes. Again, it's not a problem
- * unless the file pointer overflows which is very unlikely with 32 bit
- * offsets and practically impossible with 64 bit offsets.
- */
-
- if (lseek(fd, 0, SEEK_SET) < 0) {
- return -1;
- }
- if (write(fd, buffer, pathLength + 1) < 0) {
- return -1;
- }
- return 0;
-}
+# define VMBLOCK_FS_NAME VMBLOCK_FUSE_FS_NAME
+# define VMBLOCK_DEVICE_NAME VMBLOCK_FUSE_DEVICE_NAME
+# define VMBLOCK_CONTROL_MOUNTPOINT VMBLOCK_FUSE_CTRL_MNTPNT
+# define VMBLOCK_DEVICE VMBLOCK_FUSE_DEVICE
+# define VMBLOCK_DEVICE_MODE VMBLOCK_FUSE_DEVICE_MODE
+# define VMBLOCK_MOUNT_POINT VMBLOCK_FUSE_MOUNT_POINT
#elif defined(linux)
-# define VMBLOCK_ADD_FILEBLOCK 98
-# define VMBLOCK_DEL_FILEBLOCK 99
+# define VMBLOCK_ADD_FILEBLOCK 98
+# define VMBLOCK_DEL_FILEBLOCK 99
# ifdef VMX86_DEVEL
-# define VMBLOCK_LIST_FILEBLOCKS 100
+# define VMBLOCK_LIST_FILEBLOCKS 100
# endif
-# define VMBLOCK_CONTROL_DIRNAME VMBLOCK_FS_NAME
-# define VMBLOCK_CONTROL_DEVNAME "dev"
-# define VMBLOCK_CONTROL_MOUNTPOINT "mountPoint"
-# define VMBLOCK_CONTROL_PROC_DIRNAME "fs/" VMBLOCK_CONTROL_DIRNAME
+# define VMBLOCK_FS_NAME "vmblock"
+# define VMBLOCK_CONTROL_DIRNAME VMBLOCK_FS_NAME
+# define VMBLOCK_CONTROL_DEVNAME "dev"
+# define VMBLOCK_CONTROL_MOUNTPOINT "mountPoint"
+# define VMBLOCK_CONTROL_PROC_DIRNAME "fs/" VMBLOCK_CONTROL_DIRNAME
# define VMBLOCK_MOUNT_POINT "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \
"/" VMBLOCK_CONTROL_MOUNTPOINT
+# define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE "/proc/" VMBLOCK_CONTROL_PROC_DIRNAME \
"/" VMBLOCK_CONTROL_DEVNAME
# define VMBLOCK_DEVICE_MODE O_WRONLY
-# define VMBLOCK_CONTROL(fd, op, path) write(fd, path, op)
#elif defined(sun) || defined(__FreeBSD__)
+# define VMBLOCK_FS_NAME "vmblock"
# define VMBLOCK_MOUNT_POINT "/var/run/" VMBLOCK_FS_NAME
+# define VMBLOCK_FS_ROOT VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE VMBLOCK_MOUNT_POINT
# define VMBLOCK_DEVICE_MODE O_RDONLY
# if defined(sun) /* if (sun) { */
# ifdef VMX86_DEVEL
# define VMBLOCK_LIST_FILEBLOCKS _IO('v', 3)
# endif
-# define VMBLOCK_CONTROL(fd, op, path) ioctl(fd, op, path)
# elif defined(__FreeBSD__) /* } else if (FreeBSD) { */
/*
# define VMBLOCK_LIST_FILEBLOCKS _IO('Z', 3)
# define VMBLOCK_PURGE_FILEBLOCKS _IO('Z', 4)
# endif
- /*
- * FreeBSD's ioctl data parameters must be of fixed size. Guarantee a safe
- * buffer of size MAXPATHLEN by copying the user's string to one of our own.
- */
-# define VMBLOCK_CONTROL(fd, cmd, path) \
-({ \
- char tpath[MAXPATHLEN]; \
- if (path != NULL) { \
- strlcpy(tpath, path, MAXPATHLEN); \
- } \
- ioctl((fd), (cmd), tpath); \
-})
+
# endif /* } */
#else
# error "Unknown platform for vmblock."
/*********************************************************
* Copyright (C) 2003 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+
+/*
+ * vnops.c --
+ *
+ * vnode operations for vmblock file system.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/dirent.h>
+#include <sys/sysmacros.h>
+#include <sys/file.h> /* FREAD, FWRITE, etc flags */
+#include <sys/fs_subr.h> /* fs_fab_acl */
+#include <sys/stat.h> /* S_IRWXU and friends */
+#include <sys/dnlc.h> /* Directory name lookup cache */
+#include <sys/signal.h> /* k_sigset_t and signal macros */
+#include <sys/proc.h> /* practive (the active process) */
+#include <sys/user.h> /* u macro for current user area */
+#include <sys/thread.h> /* curthread and curproc macros */
+#include <vm/seg_vn.h> /* segment vnode mapping for mmap() */
+#include <sys/vmsystm.h> /* VM address mapping functions */
+#include <sys/systm.h> /* strlen() */
+
+#include "vmblock.h"
+#include "module.h"
+#include "block.h"
+
+
+extern int VMBlockVnodePut(struct vnode *vp);
+extern int VMBlockVnodeGet(struct vnode **vpp, struct vnode *realVp,
+ const char *name, size_t nameLen,
+ struct vnode *dvp, struct vfs *vfsp, Bool isRoot);
+
+/*
+ * Vnode Entry Points
+ */
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockOpen --
+ *
+ * Invoked when open(2) is called on a file in our filesystem.
+ *
+ * "Opens a file referenced by the supplied vnode. The open() system call
+ * has already done a vop_lookup() on the path name, which returned a vnode
+ * pointer and then calls to vop_open(). This function typically does very
+ * little since most of the real work was performed by vop_lookup()."
+ * (Solaris Internals, p537)
+ *
+ * Results:
+ * Zero on success, error code on error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockOpen(struct vnode **vpp, // IN: Vnode for file to open
+ int flag, // IN: Open flags
+ struct cred *cr // IN: Credentials of caller
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+#endif
+ )
+{
+ VMBlockMountInfo *mip;
+ Bool isRoot = TRUE;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockOpen: entry\n");
+
+ /*
+ * The opened vnode is held for us, so we don't need to do anything here
+ * except make sure only root opens the mount point.
+ */
+ mip = VPTOMIP(*vpp);
+ if (mip->root == *vpp) {
+ isRoot = crgetuid(cr) == 0;
+ }
+
+ return isRoot ? 0 : EACCES;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockClose --
+ *
+ * Invoked when a user calls close(2) on a file in our filesystem.
+ *
+ * "Closes the file given by the supplied vnode. When this is the last
+ * close, some filesystems use vop_close() to initiate a writeback of
+ * outstanding dirty pages by checking the reference cound in the vnode."
+ * (Solaris Internals, p536)
+ *
+ * Results:
+ * Zero on success, error code on error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockClose(struct vnode *vp, // IN: Vnode of file that is being closed
+ int flag, // IN: Flags file was opened with
+ int count, // IN: Reference count on this vnode
+ offset_t offset, // IN: File offset
+ struct cred *cr // IN :Credentials of caller
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+#endif
+ )
+{
+ VMBlockMountInfo *mip;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockClose: entry\n");
+
+ /*
+ * If someone is closing the root of our file system (the mount point), then
+ * we need to remove all blocks that were added by this thread. Note that
+ * Solaris calls close with counts greater than one, but we only want to
+ * actually close the file when the count reaches one.
+ */
+ mip = VPTOMIP(vp);
+ if (count == 1 && vp == mip->root) {
+ BlockRemoveAllBlocks(curthread);
+ }
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockIoctl --
+ *
+ * Invoked when a user calls ioctl(2) on a file in our filesystem.
+ * Performs a specified operation on the file.
+ *
+ * Results:
+ * Zero on success, error code on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockIoctl(struct vnode *vp, // IN: Vnode of file to operate on
+ int cmd, // IN: Requested command from user
+ intptr_t arg, // IN: Arguments for command
+ int flag, // IN: File pointer flags and data model
+ struct cred *cr, // IN: Credentials of caller
+ int *rvalp // OUT: Return value on success
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+#endif
+ )
+{
+ VMBlockMountInfo *mip;
+ int ret;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockIoctl: entry\n");
+
+ mip = VPTOMIP(vp);
+ if (vp != mip->root) {
+ return ENOTSUP;
+ }
+
+ if (rvalp) {
+ *rvalp = 0;
+ }
+
+ switch (cmd) {
+ case VMBLOCK_ADD_FILEBLOCK:
+ case VMBLOCK_DEL_FILEBLOCK:
+ {
+ struct pathname pn;
+
+ ret = pn_get((char *)arg, UIO_USERSPACE, &pn);
+ if (ret) {
+ goto out;
+ }
+
+ /* Remove all trailing path separators. */
+ while (pn.pn_pathlen > 0 && pn.pn_path[pn.pn_pathlen - 1] == '/') {
+ pn.pn_path[pn.pn_pathlen - 1] = '\0';
+ pn.pn_pathlen--;
+ }
+
+ ret = cmd == VMBLOCK_ADD_FILEBLOCK ?
+ BlockAddFileBlock(pn.pn_path, curthread) :
+ BlockRemoveFileBlock(pn.pn_path, curthread);
+ pn_free(&pn);
+ break;
+ }
+#ifdef VMX86_DEVEL
+ case VMBLOCK_LIST_FILEBLOCKS:
+ BlockListFileBlocks();
+ ret = 0;
+ break;
+#endif
+ default:
+ Warning("VMBlockIoctl: unknown command (%d) received.\n", cmd);
+ return ENOTSUP;
+ }
+
+out:
+ return ret;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockGetattr --
+ *
+ * "Gets the attributes for the supplied vnode." (Solaris Internals, p536)
+ *
+ * Results:
+ * Zero on success, error code on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockGetattr(struct vnode *vp, // IN: Vnode of file to get attributes for
+ struct vattr *vap, // OUT: Filled in with attributes of file
+ int flags, // IN: Getattr flags (see ATTR_ in vnode.h)
+ struct cred *cr // IN: Credentials of caller
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+#endif
+ )
+{
+ VMBlockMountInfo *mip;
+ VMBlockVnodeInfo *vip;
+ int ret;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockGetattr: entry\n");
+
+ mip = VPTOMIP(vp);
+ vip = VPTOVIP(vp);
+
+ ASSERT(mip);
+ ASSERT(vip);
+
+ ret = VOP_GETATTR(vip->realVnode, vap, flags, cr
+#if OS_VFS_VERSION >= 5
+ , ctx
+#endif
+ );
+ if (ret) {
+ return ret;
+ }
+
+ if (vp == mip->root) {
+ vap->va_type = VDIR;
+ } else {
+ vap->va_type = VLNK;
+ }
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockAccess --
+ *
+ * This function is invoked when the user calls access(2) on a file in our
+ * filesystem. It checks to ensure the user has the specified type of
+ * access to the file.
+ *
+ * Results:
+ * Zero if access is allowed, error code otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockAccess(struct vnode *vp, // IN: Vnode of file to check access for
+ int mode, // IN: Mode of access
+ int flags, // IN: Flags
+ struct cred *cr // IN: Credentials of caller
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+#endif
+ )
+{
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockAccess: entry\n");
+
+ /* Success */
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockLookup --
+ *
+ * Looks in the provided directory for the specified filename. Only
+ * succeeds and creates a vmblock vnode if nm exists in the redirect path.
+ *
+ * "Looks up the path name for the supplied vnode. The vop_lookup() does
+ * file-name translation for the open, stat system calls." (Solaris
+ * Internals, p537)
+ *
+ * Results:
+ * Returns zero on success and ENOENT if the file cannot be found
+ * If file is found, a vnode representing the file is returned in vpp.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockLookup(struct vnode *dvp, // IN: Directory to look in
+ char *nm, // IN: Name of component to lookup in directory
+ struct vnode **vpp, // OUT: Pointer to vnode representing found file
+ struct pathname *pnp,// IN: Full pathname being looked up
+ int flags, // IN: Lookup flags (see vnode.h)
+ struct vnode *rdir, // IN: Vnode of root device
+ struct cred *cr // IN: Credentials of caller
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+ , int *direntflags // IN:
+ , struct pathname *rpnp // IN:
+#endif
+ )
+{
+ struct vnode *realVp;
+ VMBlockMountInfo *mip;
+ int ret;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMblockLookup: entry\n");
+
+ /* First ensure that we are looking in a directory. */
+ if (dvp->v_type != VDIR) {
+ return ENOTDIR;
+ }
+
+ /* Don't invoke lookup for ourself. */
+ if (nm[0] == '\0' || (nm[0] == '.' && nm[1] == '\0')) {
+ VN_HOLD(dvp);
+ *vpp = dvp;
+ return 0;
+ }
+
+ *vpp = NULL;
+
+ /* Make sure nm exists before creating our link to it. */
+ mip = VPTOMIP(dvp);
+ ret = VOP_LOOKUP(mip->redirectVnode, nm, &realVp, pnp, flags, rdir, cr
+#if OS_VFS_VERSION >= 5
+ , ctx, direntflags, rpnp
+#endif
+ );
+ if (ret) {
+ return ret;
+ }
+
+ ret = VMBlockVnodeGet(vpp, realVp, nm, strlen(nm), dvp, dvp->v_vfsp, FALSE);
+ if (ret) {
+ VN_RELE(realVp);
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockReaddir --
+ *
+ * Reads as many entries from the directory as will fit in to the provided
+ * buffer.
+ *
+ * "The vop_readdir() method reads chunks of the directory into a uio
+ * structure. Each chunk can contain as many entries as will fit within
+ * the size supplied by the uio structure. The uio_resid structure member
+ * shows the size of the getdents request in bytes, which is divided by the
+ * size of the directory entry made by the vop_readdir() method to
+ * calculate how many directory entries to return." (Solaris Internals,
+ * p555)
+ *
+ * Results:
+ * Zero on success, error code on failure.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockReaddir(struct vnode *vp, // IN: Vnode of directory to read
+ struct uio *uiop, // IN: User's read request
+ struct cred *cr, // IN: Credentials of caller
+ int *eofp // OUT: Indicates we are done
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+ , int flags // IN: flags
+#endif
+ )
+{
+ VMBlockMountInfo *mip;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockReaddir: entry\n");
+
+ mip = (VMBlockMountInfo *)vp->v_vfsp->vfs_data;
+ return VOP_READDIR(mip->redirectVnode, uiop, cr, eofp
+#if OS_VFS_VERSION >= 5
+ , ctx, flags
+#endif
+ );
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockReadlink --
+ *
+ * "Follows the symlink in the supplied vnode." (Solaris Internals, p537)
+ *
+ * Results:
+ * Zero on success, error code on failure.
+ *
+ * Side effects:
+ * Blocks if a block has been placed on this file.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMBlockReadlink(struct vnode *vp, // IN: Vnode for the symlink
+ struct uio *uiop, // IN: IO request structure
+ struct cred *cr // IN: Credentials of caller
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+#endif
+ )
+{
+ VMBlockMountInfo *mip;
+ VMBlockVnodeInfo *vip;
+ int ret;
+
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockReadlink: entry\n");
+
+ mip = VPTOMIP(vp);
+ vip = VPTOVIP(vp);
+
+ if (vip->nameLen + 1 >= uiop->uio_resid) {
+ Warning("VMBlockReadlink: name is too long for provided buffer\n");
+ return ENAMETOOLONG;
+ }
+
+ BlockWaitOnFile(vip->name, NULL);
+
+ /* Copy path to user space. */
+ ASSERT(vip->name[vip->nameLen] == '\0');
+ ret = uiomove(vip->name, vip->nameLen + 1, UIO_READ, uiop);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMBlockInactive --
+ *
+ * Frees a vnode that is no longer referenced.
+ *
+ * "Free resources and releases the supplied vnode. The file system can
+ * choose to destroy the vnode or put it onto an inactive list, which is
+ * managed by the file system implementation." (Solaris Internals, p536)
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+VMBlockInactive(struct vnode *vp, // IN: Vnode to operate on
+ struct cred *cr // IN: Credentials of the caller
+#if OS_VFS_VERSION >= 5
+ , caller_context_t *ctx // IN: Caller's context
+#endif
+ )
+{
+ Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockInactive: entry\n");
+
+ VMBlockVnodePut(vp);
+}
+
+const fs_operation_def_t vnodeOpsArr[] = {
+ VMBLOCK_VOP(VOPNAME_OPEN, vop_open, VMBlockOpen),
+ VMBLOCK_VOP(VOPNAME_CLOSE, vop_close, VMBlockClose),
+ VMBLOCK_VOP(VOPNAME_IOCTL, vop_ioctl, VMBlockIoctl),
+ VMBLOCK_VOP(VOPNAME_GETATTR, vop_getattr, VMBlockGetattr),
+ VMBLOCK_VOP(VOPNAME_ACCESS, vop_access, VMBlockAccess),
+ VMBLOCK_VOP(VOPNAME_LOOKUP, vop_lookup, VMBlockLookup),
+ VMBLOCK_VOP(VOPNAME_READDIR, vop_readdir, VMBlockReaddir),
+ VMBLOCK_VOP(VOPNAME_READLINK, vop_readlink, VMBlockReadlink),
+#if OS_VFS_VERSION <=3
+ VMBLOCK_VOP(VOPNAME_INACTIVE, vop_inactive,
+ (fs_generic_func_p)VMBlockInactive),
+#else
+ VMBLOCK_VOP(VOPNAME_INACTIVE, vop_inactive, VMBlockInactive),
+#endif
+ { NULL }
+};
+
*----------------------------------------------------------------------------
*/
-#if HGFS_VFS_VERSION > 2
#if HGFS_VFS_VERSION == 3
-int
+int HgfsFreevfs(vfs_t *vfsp)
#else
-void
+void HgfsFreevfs(vfs_t *vfsp)
#endif
-HgfsFreevfs(struct vfs *vfsp)
{
DEBUG(VM_DEBUG_ENTRY, "HgfsFreevfs().\n");
return 0;
#endif
}
-#endif
#if HGFS_VFS_VERSION > 2
#elif defined(__APPLE__) && defined(KERNEL)
+#include "availabilityMacOS.h"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// The Mac OS 10.5 kernel SDK defines va_copy in stdarg.h.
+#include <stdarg.h>
+#else
/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
+ * The Mac OS 10.4 kernel SDK needs va_copy. Based on inspection of
+ * stdarg.h from the MacOSX10.4u.sdk kernel framework, this should
+ * work.
*/
-
#define va_copy(dest, src) ((dest) = (src))
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#elif defined(__GNUC__) && (__GNUC__ < 3)
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
static int HgfsGetNextDirEntry(HgfsSuperInfo *sip, HgfsHandle handle,
uint32_t offset, char *nameOut, Bool *done);
static int HgfsDoRead(HgfsSuperInfo *sip, HgfsHandle handle, uint64_t offset,
- uint32_t size, uio_t *uiop);
+ uint32_t size, uio_t *uiop, uint32_t *count);
static int HgfsDoWrite(HgfsSuperInfo *sip, HgfsHandle handle, int ioflag,
- uint64_t offset, uint32_t size, uio_t *uiop);
+ uint64_t offset, uint32_t size, uio_t *uiop,
+ uint32_t *count);
static int HgfsDelete(HgfsSuperInfo *sip, char *filename, HgfsOp op);
static int HgfsSubmitRequest(HgfsSuperInfo *sip, HgfsReq *req);
static int HgfsValidateReply(HgfsReq *req, uint32_t minSize);
+static int HgfsStatusConvertToSolaris(HgfsStatus hgfsStatus);
static void HgfsAttrToSolaris(struct vnode *vp, const HgfsAttr *hgfsAttr,
struct vattr *solAttr);
static Bool HgfsSetattrCopy(struct vattr *solAttr, int flags,
*/
do {
uint32_t size;
+ uint32_t count;
- DEBUG(VM_DEBUG_INFO, "HgfsRead: offset=%"FMT64"d, uio_loffset=%lld\n",
- offset, uiop->uio_loffset);
- DEBUG(VM_DEBUG_HANDLE, "HgfsRead: ** handle=%d, file=%s\n",
- handle, HGFS_VP_TO_FILENAME(vp));
+ DEBUG(VM_DEBUG_INFO, "%s: offset=%"FMT64"d, uio_loffset=%lld\n",
+ __func__, offset, uiop->uio_loffset);
+ DEBUG(VM_DEBUG_HANDLE, "%s: ** handle=%d, file=%s\n",
+ __func__, handle, HGFS_VP_TO_FILENAME(vp));
/* Request at most HGFS_IO_MAX bytes */
size = (uiop->uio_resid > HGFS_IO_MAX) ? HGFS_IO_MAX : uiop->uio_resid;
/* Send one read request. */
- ret = HgfsDoRead(sip, handle, offset, size, uiop);
- if (ret == 0) {
+ ret = HgfsDoRead(sip, handle, offset, size, uiop, &count);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: HgfsDoRead() failed.\n", __func__);
+ return ret;
+ }
+
+ if (count == 0) {
/* On end of file we return success */
- DEBUG(VM_DEBUG_DONE, "HgfsRead: end of file reached.\n");
+ DEBUG(VM_DEBUG_DONE, "%s: end of file reached.\n", __func__);
return 0;
- } else if (ret < 0) {
- /*
- * HgfsDoRead() returns the negative of an appropriate error code to
- * differentiate between success and error cases. We flip the sign
- * and return the appropriate error code. See the HgfsDoRead()
- * function header for a fuller explanation.
- */
- DEBUG(VM_DEBUG_FAIL, "HgfsRead: HgfsDoRead() failed.\n");
- return -ret;
}
/* Bump the offset past where we have already read. */
- offset += ret;
+ offset += count;
} while (uiop->uio_resid);
/* We fulfilled the user's read request, so return success. */
- DEBUG(VM_DEBUG_DONE, "HgfsRead: done.\n");
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
return 0;
}
*/
do {
uint32_t size;
+ uint32_t count;
DEBUG(VM_DEBUG_INFO, "HgfsWrite: ** offset=%"FMT64"d, uio_loffset=%lld\n",
offset, uiop->uio_loffset);
size = (uiop->uio_resid > HGFS_IO_MAX) ? HGFS_IO_MAX : uiop->uio_resid;
/* Send one write request. */
- ret = HgfsDoWrite(sip, handle, ioflag, offset, size, uiop);
- if (ret < 0) {
- /*
- * As in HgfsRead(), we need to flip the sign. See the comment in the
- * function header of HgfsDoWrite() for a more complete explanation.
- */
- DEBUG(VM_DEBUG_INFO, "HgfsWrite: HgfsDoWrite failed, returning %d\n", -ret);
- return -ret;
+ ret = HgfsDoWrite(sip, handle, ioflag, offset, size, uiop, &count);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: HgfsDoRead() failed.\n", __func__);
+ return ret;
}
/* Increment the offest by the amount already written. */
- offset += ret;
-
+ offset += count;
} while (uiop->uio_resid);
/* We have completed the user's write request, so return success. */
goto out;
}
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
+ } else {
/* Make sure we got all of the attributes */
if (req->packetSize != sizeof *reply) {
- DEBUG(VM_DEBUG_FAIL, "HgfsGetattr: packet too small.\n");
+ DEBUG(VM_DEBUG_FAIL, "%s: packet too small.\n", __func__);
ret = EIO;
- break;
- }
-
- DEBUG(VM_DEBUG_COMM, "HgfsGetattr: received reply for ID %d\n",
- reply->header.id);
- DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n",
- reply->header.status);
- DEBUG(VM_DEBUG_COMM, " file type: %d\n", reply->attr.type);
- DEBUG(VM_DEBUG_COMM, " file size: %"FMT64"u\n", reply->attr.size);
- DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.permissions);
- DEBUG(VM_DEBUG_COMM, "HgfsGetattr: filename %s\n", HGFS_VP_TO_FILENAME(vp));
+ } else {
- /* Map the Hgfs attributes into the Solaris attributes */
- HgfsAttrToSolaris(vp, &reply->attr, vap);
+ DEBUG(VM_DEBUG_COMM, "%s: received reply for ID %d\n",
+ __func__, reply->header.id);
+ DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n",
+ reply->header.status);
+ DEBUG(VM_DEBUG_COMM, " file type: %d\n", reply->attr.type);
+ DEBUG(VM_DEBUG_COMM, " file size: %"FMT64"u\n", reply->attr.size);
+ DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.permissions);
+ DEBUG(VM_DEBUG_COMM, "%s: filename %s\n", __func__, HGFS_VP_TO_FILENAME(vp));
- DEBUG(VM_DEBUG_DONE, "HgfsGetattr: done.\n");
- break;
+ /* Map the Hgfs attributes into the Solaris attributes */
+ HgfsAttrToSolaris(vp, &reply->attr, vap);
- /* We'll add other error codes based on status here */
- default:
- ret = EIO;
- break;
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
+ }
}
out:
goto out;
}
- switch(reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- /* Success handled after switch. */
- break;
-
- case HGFS_STATUS_NO_SUCH_FILE_OR_DIR:
- case HGFS_STATUS_INVALID_NAME:
- DEBUG(VM_DEBUG_FAIL, "HgfsSetattr: no such file or directory.\n");
- ret = ENOENT;
- goto out;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_FAIL, "HgfsSetattr: operation not permitted.\n");
- ret = EPERM;
- goto out;
-
- default:
- DEBUG(VM_DEBUG_FAIL, "HgfsSetattr: default error.\n");
- ret = EPROTO;
- goto out;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
+ } else {
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
}
- /* Success */
- ret = 0;
- DEBUG(VM_DEBUG_DONE, "HgfsSetattr: done.\n");
-
out:
HgfsDestroyReq(sip, req);
return ret;
DEBUG(VM_DEBUG_COMM, " file size: %"FMT64"u\n", reply->attr.size);
DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.permissions);
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- /* Ensure packet contains correct amount of data */
- if (req->packetSize != sizeof *reply) {
- DEBUG(VM_DEBUG_COMM,
- "HgfsLookup: invalid packet size received for \"%s\".\n", nm);
- ret = EIO;
- goto out;
- }
- /* Success */
- break;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_LOG, "HgfsLookup: operation not permitted on \"%s\".\n", nm);
- ret = EACCES;
- goto out;
-
- case HGFS_STATUS_NO_SUCH_FILE_OR_DIR:
- case HGFS_STATUS_INVALID_NAME:
- /*
- * Note, this is necessary because before creating a file Solaris does
- * a lookup to make sure it doesn't already exist. We need to return
- * ENOENT in this case.
- */
- DEBUG(VM_DEBUG_LOG, "HgfsLookup: \"%s\" does not exist.\n", nm);
- ret = ENOENT;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed for [%s] with error %d.\n",
+ __func__, nm, ret);
goto out;
+ }
- default:
- DEBUG(VM_DEBUG_LOG, "HgfsLookup: error on \"%s\".\n", nm);
+ /* Ensure packet contains correct amount of data */
+ if (req->packetSize != sizeof *reply) {
+ DEBUG(VM_DEBUG_COMM, "%s: invalid packet size received for [%s].\n",
+ __func__, nm);
ret = EIO;
goto out;
}
ret = EIO;
goto out;
}
+
/* HgfsVnodeGet guarantees this. */
ASSERT(*vpp);
}
/* Return appropriate value. */
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- /* Handled after switch. */
- break;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_FAIL, "HgfsRename: operation not permitted.\n");
- ret = EACCES;
- goto out;
-
- case HGFS_STATUS_NOT_DIRECTORY:
- DEBUG(VM_DEBUG_FAIL, "HgfsRename: not a directory.\n");
- ret = ENOTDIR;
- goto out;
-
- case HGFS_STATUS_DIR_NOT_EMPTY:
- DEBUG(VM_DEBUG_FAIL, "HgfsRename: directory not empty.\n");
- ret = EEXIST;
- goto out;
-
- case HGFS_STATUS_NO_SUCH_FILE_OR_DIR:
- case HGFS_STATUS_INVALID_NAME:
- DEBUG(VM_DEBUG_FAIL, "HgfsRename: no such file or directory.\n");
- ret = ENOENT;
- goto out;
-
- default:
- DEBUG(VM_DEBUG_FAIL, "HgfsRename: default error.\n");
- ret = EPROTO;
- goto out;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
+ } else {
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
}
-
- /* Successfully renamed file. */
- ret = 0;
- DEBUG(VM_DEBUG_DONE, "HgfsRename: done.\n");
-
out:
HgfsDestroyReq(sip, req);
return ret;
goto out;
}
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- /* Handled below switch. */
- break;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_FAIL, "HgfsMkdir: operation not permitted.\n");
- ret = EACCES;
- goto out;
-
- case HGFS_STATUS_FILE_EXISTS:
- DEBUG(VM_DEBUG_FAIL, "HgfsMkdir: directory already exists.\n");
- ret = EEXIST;
- goto out;
-
- default:
- ret = EPROTO;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
goto out;
}
DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status);
DEBUG(VM_DEBUG_COMM, " handle: %d\n", reply->search);
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- if (req->packetSize != sizeof *reply) {
- DEBUG(VM_DEBUG_FAIL, "HgfsDirOpen: incorrect packet size.\n");
- ret = EIO;
- goto out;
- }
- /* Success handled after switch. */
- break;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_FAIL, "HgfsDirOpen: operation not permitted (%s).\n",
- HGFS_VP_TO_FILENAME(vp));
- ret = EACCES;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed for [%s] with error %d.\n",
+ __func__, HGFS_VP_TO_FILENAME(vp), ret);
goto out;
+ }
- default:
- DEBUG(VM_DEBUG_FAIL, "HgfsDirOpen: default error (%s).\n",
- HGFS_VP_TO_FILENAME(vp));
- ret = EPROTO;
+ if (req->packetSize != sizeof *reply) {
+ DEBUG(VM_DEBUG_FAIL, "HgfsDirOpen: incorrect packet size.\n");
+ ret = EIO;
goto out;
}
goto out;
}
- ret = 0; /* Return success */
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
out:
/* Make sure we put the request back on the list */
HgfsDestroyReq(sip, req);
- DEBUG(VM_DEBUG_DONE, "HgfsDirOpen: done\n");
return ret;
}
goto out;
}
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- if (req->packetSize != sizeof *reply) {
- DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: size of reply is incorrect.\n");
- ret = EIO;
- goto out;
- }
-
- /* Success case is handled after switch. */
- break;
-
- case HGFS_STATUS_NO_SUCH_FILE_OR_DIR:
- case HGFS_STATUS_INVALID_NAME:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: no such file \"%s\".\n",
- HGFS_VP_TO_FILENAME(vp));
- ret = ENOENT;
- goto out;
-
- case HGFS_STATUS_FILE_EXISTS:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: \"%s\" exists.\n",
- HGFS_VP_TO_FILENAME(vp));
- ret = EEXIST;
- goto out;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: operation not permitted on %s.\n",
- HGFS_VP_TO_FILENAME(vp));
- ret = EACCES;
- goto out;
-
- case HGFS_STATUS_ACCESS_DENIED:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: access denied on %s.\n",
- HGFS_VP_TO_FILENAME(vp));
- ret = EACCES;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed for [%s] with error %d.\n",
+ __func__, HGFS_VP_TO_FILENAME(vp), ret);
goto out;
+ }
- default:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileOpen: default/unknown error %d.\n",
- reply->header.status);
- ret = EACCES;
+ if (req->packetSize != sizeof *reply) {
+ DEBUG(VM_DEBUG_FAIL, "%s: size of reply is incorrect.\n", __func__);
+ ret = EIO;
goto out;
}
goto out;
}
- ret = 0;
-
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
out:
HgfsDestroyReq(sip, req);
DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status);
/* Ensure server was able to close directory. */
- if (reply->header.status != HGFS_STATUS_SUCCESS) {
- ret = EIO;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
goto out;
}
/* Now clear this open file's handle for future use. */
ret = HgfsClearOpenFileHandle(vp);
if (ret) {
- DEBUG(VM_DEBUG_FAIL, "HgfsDirClose: couldn't clear handle.\n");
+ DEBUG(VM_DEBUG_FAIL, "%s: couldn't clear handle.\n", __func__);
ret = EINVAL;
req->state = HGFS_REQ_ERROR;
goto out;
}
/* The directory was closed successfully so we return success. */
- ret = 0;
-
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
out:
HgfsDestroyReq(sip, req);
reply = (HgfsReplyClose *)req->packet;
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- /*
- * We already verified the size of the reply above since this reply type
- * only contains a header, so we just clear the handle and return success.
- */
- ret = HgfsClearOpenFileHandle(vp);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "HgfsFileClose: couldn't clear handle.\n");
- ret = EINVAL;
- req->state = HGFS_REQ_ERROR;
- goto out;
- }
-
- ret = 0;
- goto out;
-
- case HGFS_STATUS_INVALID_HANDLE:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileClose: invalid handle error.\n");
- ret = EPROTO;
- goto out;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileClose: operation not permitted error.\n");
- ret = EACCES;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
goto out;
+ }
- default:
- DEBUG(VM_DEBUG_FAIL, "HgfsFileClose: other/unknown error.\n");
- ret = EPROTO;
+ /*
+ * We already verified the size of the reply above since this reply type
+ * only contains a header, so we just clear the handle and return success.
+ */
+ ret = HgfsClearOpenFileHandle(vp);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: couldn't clear handle.\n", __func__);
+ ret = EINVAL;
+ req->state = HGFS_REQ_ERROR;
goto out;
}
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
+
out:
HgfsDestroyReq(sip, req);
DEBUG(VM_DEBUG_DONE, "HgfsFileClose: returning %d\n", ret);
DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", reply->header.status);
/* Now ensure the server didn't have an error */
- if (reply->header.status != HGFS_STATUS_SUCCESS) {
- DEBUG(VM_DEBUG_FAIL, "HgfsGetNextDirEntry: server didn't return success (%d).\n",
- reply->header.status);
- ret = EINVAL;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
goto out;
}
/* Make sure we got an entire reply (excluding filename) */
if (req->packetSize < sizeof *reply) {
- DEBUG(VM_DEBUG_FAIL, "HgfsGetNextDirEntry: server didn't provide entire reply.\n");
+ DEBUG(VM_DEBUG_FAIL, "%s: server didn't provide entire reply.\n",
+ __func__);
ret = EIO;
goto out;
}
/* See if there are no more filenames to read */
if (reply->fileName.length <= 0) {
- DEBUG(VM_DEBUG_DONE, "HgfsGetNextDirEntry: no more directory entries.\n");
+ DEBUG(VM_DEBUG_DONE, "%s: no more directory entries.\n", __func__);
*done = TRUE;
ret = 0; /* return success */
goto out;
/* Make sure filename isn't too long */
if ((reply->fileName.length > MAXNAMELEN) ||
(reply->fileName.length > HGFS_PAYLOAD_MAX(reply)) ) {
- DEBUG(VM_DEBUG_FAIL, "HgfsGetNextDirEntry: filename is too long.\n");
+ DEBUG(VM_DEBUG_FAIL, "%s: filename is too long.\n", __func__);
ret = EOVERFLOW;
goto out;
}
nameOut[reply->fileName.length] = '\0';
ret = 0;
- DEBUG(VM_DEBUG_DONE, "HgfsGetNextDirEntry: done.\n");
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
+
out:
HgfsDestroyReq(sip, req);
return ret;
* This function is called repeatedly by HgfsRead() with requests of size
* less than or equal to HGFS_IO_MAX.
*
- * Note that we return the negative of an appropriate error code in this
- * function so we can differentiate between success and failure. On success
- * we need to return the number of bytes read, but Solaris' error codes are
- * positive so we negate them before returning. If callers want to return
- * these error codes to the Kernel, they will need to flip their sign.
- *
* Results:
- * Returns number of bytes read on success and a negative value on error.
+ * Returns 0 on success and a positive value on error.
*
* Side effects:
- * On success, size bytes are written into the user's buffer.
+ * On success, up to 'size' bytes are written into the user's buffer.
+ * Actual number of bytes written passed back in 'count' argument.
*
*----------------------------------------------------------------------------
*/
HgfsHandle handle, // IN: Server's handle to read from
uint64_t offset, // IN: File offset to read at
uint32_t size, // IN: Number of bytes to read
- uio_t *uiop) // IN: Defines user's read request
+ uio_t *uiop, // IN: Defines user's read request
+ uint32_t *count) // OUT: Number of bytes read
{
HgfsReq *req;
HgfsRequestRead *request;
ASSERT(sip);
ASSERT(uiop);
ASSERT(size <= HGFS_IO_MAX); // HgfsRead() should guarantee this
+ ASSERT(count);
- DEBUG(VM_DEBUG_ENTRY, "HgfsDoRead: entry.\n");
+ DEBUG(VM_DEBUG_ENTRY, "%s: entry.\n", __func__);
req = HgfsGetNewReq(sip);
if (!req) {
- return -EIO;
+ return EIO;
}
request = (HgfsRequestRead *)req->packet;
ret = HgfsSubmitRequest(sip, req);
if (ret) {
- /*
- * We need to flip the sign of the return value to indicate error; see
- * the comment in the function header.
- */
- ret = -ret;
+ DEBUG(VM_DEBUG_FAIL, "%s: HgfsSubmitRequest failed.\n", __func__);
goto out;
}
/* Ensure we got an entire header. */
if (HgfsValidateReply(req, sizeof reply->header) != 0) {
- DEBUG(VM_DEBUG_FAIL, "HgfsDoRead: invalid reply received.\n");
- ret = -EPROTO;
+ DEBUG(VM_DEBUG_FAIL, "%s: invalid reply received.\n"i, __func__);
+ ret = EPROTO;
goto out;
}
- if (reply->header.status != HGFS_STATUS_SUCCESS) {
- DEBUG(VM_DEBUG_FAIL, "HgfsDoRead: request not completed successfully.\n");
- ret = -EACCES;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
goto out;
}
* o actualSize is zero, which indicates the end of the file (and success)
* o actualSize is greater than size, which indicates a server error
*/
- if (reply->actualSize <= size) {
- /* If we didn't get any data, we don't need to copy to the user. */
- if (reply->actualSize == 0) {
- goto success;
- }
+ if (reply->actualSize > size) {
+ /* We got too much data: server error. */
+ DEBUG(VM_DEBUG_FAIL, "%s: received too much data in payload.\n",
+ __func__);
+ ret = EPROTO;
+ goto out;
+ }
- /* Perform the copy to the user */
+ /* Perform the copy to the user if we have something to copy */
+ if (reply->actualSize > 0) {
ret = uiomove(reply->payload, reply->actualSize, UIO_READ, uiop);
if (ret) {
- ret = -EIO;
+ DEBUG(VM_DEBUG_FAIL, "%s: uiomove failed, rc: %d\n.",
+ __func__, ret);
+ ret = EIO;
goto out;
}
-
- /* We successfully copied the payload to the user's buffer */
- goto success;
-
- } else {
- /* We got too much data: server error. */
- DEBUG(VM_DEBUG_FAIL, "HgfsDoRead: received too much data in payload.\n");
- ret = -EPROTO;
- goto out;
}
+ *count = reply->actualSize;
+ DEBUG(VM_DEBUG_DONE, "%s: successfully read %d bytes to user.\n",
+ __func__, *count);
-success:
- ret = reply->actualSize;
- DEBUG(VM_DEBUG_DONE, "HgfsDoRead: successfully read %d bytes to user.\n", ret);
out:
HgfsDestroyReq(sip, req);
return ret;
* This function is called repeatedly by HgfsWrite() with requests of size
* less than or equal to HGFS_IO_MAX.
*
- * Note that we return the negative of an appropriate error code in this
- * function so we can differentiate between success and failure. On success
- * we need to return the number of bytes written, but Solaris' error codes are
- * positive so we negate them before returning. If callers want to return
- * these error codes to the kernel, they will need to flip their sign.
- *
* Results:
- * Returns number of bytes written on success and a negative value on error.
+ * Returns number 0 on success and a positive value on error.
*
* Side effects:
- * On success, size bytes are written to the file specified by the handle.
+ * On success, up to 'size' bytes are written to the file specified by the
+ * handle. Actual number of bytes written passed back in 'count' argument.
*
*----------------------------------------------------------------------------
*/
int ioflag, // IN: Flags for write
uint64_t offset, // IN: Where in the file to begin writing
uint32_t size, // IN: How much data to write
- uio_t *uiop) // IN: Describes user's write request
+ uio_t *uiop, // IN: Describes user's write request
+ uint32_t *count) // OUT: number of bytes written
{
HgfsReq *req;
HgfsRequestWrite *request;
ASSERT(sip);
ASSERT(uiop);
ASSERT(size <= HGFS_IO_MAX); // HgfsWrite() guarantees this
+ ASSERT(count);
+
+ DEBUG(VM_DEBUG_ENTRY, "%s: entry.\n", __func__);
req = HgfsGetNewReq(sip);
if (!req) {
- return -EIO;
+ return EIO;
}
request = (HgfsRequestWrite *)req->packet;
request->requiredSize = size;
if (ioflag & FAPPEND) {
- DEBUG(VM_DEBUG_COMM, "HgfsDoWrite: writing in append mode.\n");
+ DEBUG(VM_DEBUG_COMM, "%s: writing in append mode.\n", __func__);
request->flags |= HGFS_WRITE_APPEND;
}
- DEBUG(VM_DEBUG_COMM, "HgfsDoWrite: requesting write of %d bytes.\n", size);
+ DEBUG(VM_DEBUG_COMM, "%s: requesting write of %d bytes.\n",
+ __func__, size);
/* Copy the data the user wants to write into the payload. */
ret = uiomove(request->payload, request->requiredSize, UIO_WRITE, uiop);
if (ret) {
DEBUG(VM_DEBUG_FAIL,
- "HgfsDoWrite: uiomove(9F) failed copying data from user.\n");
- ret = -EIO;
+ "%s: uiomove(9F) failed copying data from user.\n", __func__);
+ ret = EIO;
/* We need to set the request state to error before destroying. */
req->state = HGFS_REQ_ERROR;
goto out;
ret = HgfsSubmitRequest(sip, req);
if (ret) {
- /*
- * As in HgfsDoRead(), we need to flip the sign of the error code
- * returned by HgfsSubmitRequest().
- */
- DEBUG(VM_DEBUG_FAIL, "HgfsDoWrite: HgfsSubmitRequest failed.\n");
- ret = -ret;
+ DEBUG(VM_DEBUG_FAIL, "%s: HgfsSubmitRequest failed.\n", __func__);
goto out;
}
reply = (HgfsReplyWrite *)req->packet;
if (HgfsValidateReply(req, sizeof reply->header) != 0) {
- DEBUG(VM_DEBUG_FAIL, "HgfsDoWrite: invalid reply received.\n");
- ret = -EPROTO;
+ DEBUG(VM_DEBUG_FAIL, "%s: invalid reply received.\n", __func__);
+ ret = EPROTO;
goto out;
}
- if (reply->header.status != HGFS_STATUS_SUCCESS) {
- DEBUG(VM_DEBUG_FAIL, "HgfsDoWrite: write failed (status=%d).\n",
- reply->header.status);
- ret = -EACCES;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
goto out;
}
if (req->packetSize != sizeof *reply) {
- DEBUG(VM_DEBUG_FAIL,
- "HgfsDoWrite: invalid size of reply on successful reply.\n");
- ret = -EPROTO;
+ DEBUG(VM_DEBUG_FAIL, "%s: invalid size of reply on successful reply.\n",
+ __func__);
+ ret = EPROTO;
goto out;
}
/* The write was completed successfully, so return the amount written. */
- ret = reply->actualSize;
- DEBUG(VM_DEBUG_DONE, "HgfsDoWrite: wrote %d bytes.\n", ret);
+ *count = reply->actualSize;
+ DEBUG(VM_DEBUG_DONE, "%s: wrote %d bytes.\n", __func__, *count);
out:
HgfsDestroyReq(sip, req);
}
/* Return the appropriate value. */
- switch (reply->header.status) {
- case HGFS_STATUS_SUCCESS:
- ret = 0;
- break;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- DEBUG(VM_DEBUG_FAIL, "HgfsDelete: operation not permitted.\n");
- ret = EACCES;
- goto out;
-
- case HGFS_STATUS_NOT_DIRECTORY:
- DEBUG(VM_DEBUG_FAIL, "HgfsDelete: not a directory.\n");
- ret = ENOTDIR;
- goto out;
-
- case HGFS_STATUS_DIR_NOT_EMPTY:
- DEBUG(VM_DEBUG_FAIL, "HgfsDelete: directory not empty.\n");
- ret = EEXIST;
- goto out;
-
- case HGFS_STATUS_NO_SUCH_FILE_OR_DIR:
- case HGFS_STATUS_INVALID_NAME:
- DEBUG(VM_DEBUG_FAIL, "HgfsDelete: no such file or directory.\n");
- ret = ENOENT;
- goto out;
- case HGFS_STATUS_ACCESS_DENIED:
- DEBUG(VM_DEBUG_FAIL, "HgfsDelete: access denied.\n");
-
- /* XXX: Add retry behavior after removing r/o bit. */
- ret = EACCES;
- goto out;
- default:
- DEBUG(VM_DEBUG_FAIL, "HgfsDelete: default error.\n");
- ret = EPROTO;
- goto out;
+ ret = HgfsStatusConvertToSolaris(reply->header.status);
+ if (ret) {
+ DEBUG(VM_DEBUG_FAIL, "%s: failed with error %d.\n",
+ __func__, ret);
+ } else {
+ DEBUG(VM_DEBUG_DONE, "%s: done.\n", __func__);
}
- DEBUG(VM_DEBUG_DONE, "HgfsDelete: done.\n");
-
out:
HgfsDestroyReq(sip, req);
return ret;
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsStatusConvertToSolaris --
+ *
+ * Convert a cross-platform HGFS status code to its kernel specific
+ * counterpart.
+ *
+ * Rather than encapsulate the status codes within an array indexed by the
+ * various HGFS status codes, we explicitly enumerate them in a switch
+ * statement, saving the reader some time when matching HGFS status codes
+ * against Solaris status codes.
+ *
+ * Results:
+ * Zero if the converted status code represents success, positive error
+ * otherwise. Unknown status codes are converted to EPROTO.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+HgfsStatusConvertToSolaris(HgfsStatus hgfsStatus) // IN: Status code to convert
+{
+ switch (hgfsStatus) {
+ case HGFS_STATUS_SUCCESS:
+ return 0;
+
+ case HGFS_STATUS_NO_SUCH_FILE_OR_DIR:
+ case HGFS_STATUS_INVALID_NAME:
+ return ENOENT;
+
+ case HGFS_STATUS_INVALID_HANDLE:
+ return EBADF;
+
+ case HGFS_STATUS_OPERATION_NOT_PERMITTED:
+ return EPERM;
+
+ case HGFS_STATUS_FILE_EXISTS:
+ return EEXIST;
+
+ case HGFS_STATUS_NOT_DIRECTORY:
+ return ENOTDIR;
+
+ case HGFS_STATUS_DIR_NOT_EMPTY:
+ return ENOTEMPTY;
+
+ case HGFS_STATUS_PROTOCOL_ERROR:
+ return EPROTO;
+
+ case HGFS_STATUS_ACCESS_DENIED:
+ case HGFS_STATUS_SHARING_VIOLATION:
+ return EACCES;
+
+ case HGFS_STATUS_NO_SPACE:
+ return ENOSPC;
+
+ case HGFS_STATUS_OPERATION_NOT_SUPPORTED:
+ return EOPNOTSUPP;
+
+ case HGFS_STATUS_NAME_TOO_LONG:
+ return ENAMETOOLONG;
+
+ case HGFS_STATUS_GENERIC_ERROR:
+ return EIO;
+
+ default:
+ DEBUG(VM_DEBUG_LOG,
+ "VMware hgfs: %s: unknown error: %u\n", __func__, hgfsStatus);
+ return EPROTO;
+ }
+}
+
+
/*
* XXX
* These were taken and slightly modified from hgfs/driver/linux/driver.c.
FLAGDEFA( 1, ECX, COMMON, 3, 1, MWAIT, NO, MASK, 0, FALSE, MWAIT) \
FLAGDEFA( 1, ECX, INTEL, 4, 1, DSCPL, NO, MASK, 0, FALSE, DSCPL) \
FLAGDEFA( 1, ECX, INTEL, 5, 1, VMX, NO, MASK, 0, FALSE, VMX) \
-FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
+FLAGDEF( 1, ECX, INTEL, 6, 1, SMX, NO, MASK, 0, FALSE) \
FLAGDEF( 1, ECX, INTEL, 7, 1, EST, NO, MASK, 0, FALSE) \
FLAGDEF( 1, ECX, INTEL, 8, 1, TM2, NO, MASK, 0, FALSE) \
FLAGDEFA( 1, ECX, COMMON, 9, 1, SSSE3, YES, HOST, 0, TRUE, SSSE3) \
FLAGDEF( 81, EDX, AMD, 23, 1, MMX, YES, HOST, 0, TRUE) \
FLAGDEF( 81, EDX, AMD, 24, 1, FXSAVE, YES, HOST, 0, TRUE) \
FLAGDEFA( 81, EDX, AMD, 25, 1, FFXSR, YES, HOST, 0, FALSE, FFXSR) \
-FLAGDEF( 81, EDX, AMD, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
+FLAGDEF( 81, EDX, COMMON, 26, 1, PDPE1GB, NO, MASK, 0, FALSE) \
FLAGDEFA( 81, EDX, COMMON, 27, 1, RDTSCP, YES, HOST, 0, TRUE, RDTSCP) \
FLAGDEFA( 81, EDX, COMMON, 29, 1, LM, YES, TEST, 1, FALSE, LM) \
FLAGDEFA( 81, EDX, AMD, 30, 1, 3DNOWPLUS, YES, HOST, 0, TRUE, 3DNOWPLUS) \
FLAGDEF( 8A, EDX, AMD, 3, 1, SVM_NRIP, NO, MASK, 0, FALSE) \
FIELDDEF( 8A, EDX, AMD, 4, 28, SVMEDX_RSVD, NO, MASK, 0, FALSE)
+
#define CPUID_FIELD_DATA \
CPUID_FIELD_DATA_LEVEL_0 \
CPUID_FIELD_DATA_LEVEL_1 \
CPUID_FIELD_DATA_LEVEL_81 \
CPUID_FIELD_DATA_LEVEL_8x
+
/*
* Define all field and flag values as an enum. The result is a full
* set of values taken from the table above in the form:
* macros/functions for reading cpuid fields.
*/
+#define CPUID_FAMILY_EXTENDED 15
+
/* Effective Intel CPU Families */
#define CPUID_FAMILY_486 4
#define CPUID_FAMILY_P5 5
#define CPUID_FAMILY_K8 15
#define CPUID_FAMILY_K8L 16
#define CPUID_FAMILY_K8MOBILE 17
-#define CPUID_FAMILY_EXTENDED 15
/* Intel model information */
#define CPUID_MODEL_PPRO 1
#define CPUID_MODEL_NEHALEM_1A 0x1a // Nehalem / Gainestown
#define CPUID_MODEL_ATOM_1C 0x1c // Silverthorne / Diamondville
#define CPUID_MODEL_CORE_1D 0x1d // Dunnington
-#define CPUID_MODEL_NEHALEM_1E 0x1e // Lynnfield
#define CPUID_MODEL_PIII_07 7
#define CPUID_MODEL_PIII_08 8
CPUID_UARCH_IS_NEHALEM(uint32 v) // IN: %eax from CPUID with %eax=1.
{
/* Assumes the CPU manufacturer is Intel. */
+ uint32 effectiveModel = CPUID_EFFECTIVE_MODEL(v);
+
return CPUID_FAMILY_IS_P6(v) &&
- (CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1A ||
- CPUID_EFFECTIVE_MODEL(v) == CPUID_MODEL_NEHALEM_1E);
+ (
+ effectiveModel == CPUID_MODEL_NEHALEM_1A);
}
static INLINE Bool
--- /dev/null
+
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+
+1. Definitions.
+
+ 1.1. "Contributor" means each individual or entity that creates
+ or contributes to the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Software, prior Modifications used by a Contributor (if any),
+ and the Modifications made by that particular Contributor.
+
+ 1.3. "Covered Software" means (a) the Original Software, or (b)
+ Modifications, or (c) the combination of files containing
+ Original Software with files containing Modifications, in
+ each case including portions thereof.
+
+ 1.4. "Executable" means the Covered Software in any form other
+ than Source Code.
+
+ 1.5. "Initial Developer" means the individual or entity that first
+ makes Original Software available under this License.
+
+ 1.6. "Larger Work" means a work which combines Covered Software or
+ portions thereof with code not governed by the terms of this
+ License.
+
+ 1.7. "License" means this document.
+
+ 1.8. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed
+ herein.
+
+ 1.9. "Modifications" means the Source Code and Executable form of
+ any of the following:
+
+ A. Any file that results from an addition to, deletion from or
+ modification of the contents of a file containing Original
+ Software or previous Modifications;
+
+ B. Any new file that contains any part of the Original
+ Software or previous Modifications; or
+
+ C. Any new file that is contributed or otherwise made
+ available under the terms of this License.
+
+ 1.10. "Original Software" means the Source Code and Executable
+ form of computer software code that is originally released
+ under this License.
+
+ 1.11. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by
+ grantor.
+
+ 1.12. "Source Code" means (a) the common form of computer software
+ code in which modifications are made and (b) associated
+ documentation included in or with such code.
+
+ 1.13. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms
+ of, this License. For legal entities, "You" includes any
+ entity which controls, is controlled by, or is under common
+ control with You. For purposes of this definition,
+ "control" means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty
+ percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, the Initial
+ Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer, to use,
+ reproduce, modify, display, perform, sublicense and
+ distribute the Original Software (or portions thereof),
+ with or without Modifications, and/or as part of a Larger
+ Work; and
+
+ (b) under Patent Claims infringed by the making, using or
+ selling of Original Software, to make, have made, use,
+ practice, sell, and offer for sale, and/or otherwise
+ dispose of the Original Software (or portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ or otherwise makes the Original Software available to a
+ third party under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: (1) for code that You delete from the Original
+ Software, or (2) for infringements caused by: (i) the
+ modification of the Original Software, or (ii) the
+ combination of the Original Software with other software
+ or devices.
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and
+ subject to third party intellectual property claims, each
+ Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor to use, reproduce,
+ modify, display, perform, sublicense and distribute the
+ Modifications created by such Contributor (or portions
+ thereof), either on an unmodified basis, with other
+ Modifications, as Covered Software and/or as part of a
+ Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either
+ alone and/or in combination with its Contributor Version
+ (or portions of such combination), to make, use, sell,
+ offer for sale, have made, and/or otherwise dispose of:
+ (1) Modifications made by that Contributor (or portions
+ thereof); and (2) the combination of Modifications made by
+ that Contributor with its Contributor Version (or portions
+ of such combination).
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first distributes or
+ otherwise makes the Modifications available to a third
+ party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: (1) for any code that Contributor has deleted
+ from the Contributor Version; (2) for infringements caused
+ by: (i) third party modifications of Contributor Version,
+ or (ii) the combination of Modifications made by that
+ Contributor with other software (except as part of the
+ Contributor Version) or other devices; or (3) under Patent
+ Claims infringed by Covered Software in the absence of
+ Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+
+ Any Covered Software that You distribute or otherwise make
+ available in Executable form must also be made available in Source
+ Code form and that Source Code form must be distributed only under
+ the terms of this License. You must include a copy of this
+ License with every copy of the Source Code form of the Covered
+ Software You distribute or otherwise make available. You must
+ inform recipients of any such Covered Software in Executable form
+ as to how they can obtain such Covered Software in Source Code
+ form in a reasonable manner on or through a medium customarily
+ used for software exchange.
+
+ 3.2. Modifications.
+
+ The Modifications that You create or to which You contribute are
+ governed by the terms of this License. You represent that You
+ believe Your Modifications are Your original creation(s) and/or
+ You have sufficient rights to grant the rights conveyed by this
+ License.
+
+ 3.3. Required Notices.
+
+ You must include a notice in each of Your Modifications that
+ identifies You as the Contributor of the Modification. You may
+ not remove or alter any copyright, patent or trademark notices
+ contained within the Covered Software, or any notices of licensing
+ or any descriptive text giving attribution to any Contributor or
+ the Initial Developer.
+
+ 3.4. Application of Additional Terms.
+
+ You may not offer or impose any terms on any Covered Software in
+ Source Code form that alters or restricts the applicable version
+ of this License or the recipients' rights hereunder. You may
+ choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of
+ Covered Software. However, you may do so only on Your own behalf,
+ and not on behalf of the Initial Developer or any Contributor.
+ You must make it absolutely clear that any such warranty, support,
+ indemnity or liability obligation is offered by You alone, and You
+ hereby agree to indemnify the Initial Developer and every
+ Contributor for any liability incurred by the Initial Developer or
+ such Contributor as a result of warranty, support, indemnity or
+ liability terms You offer.
+
+ 3.5. Distribution of Executable Versions.
+
+ You may distribute the Executable form of the Covered Software
+ under the terms of this License or under the terms of a license of
+ Your choice, which may contain terms different from this License,
+ provided that You are in compliance with the terms of this License
+ and that the license for the Executable form does not attempt to
+ limit or alter the recipient's rights in the Source Code form from
+ the rights set forth in this License. If You distribute the
+ Covered Software in Executable form under a different license, You
+ must make it absolutely clear that any terms which differ from
+ this License are offered by You alone, not by the Initial
+ Developer or Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred
+ by the Initial Developer or such Contributor as a result of any
+ such terms You offer.
+
+ 3.6. Larger Works.
+
+ You may create a Larger Work by combining Covered Software with
+ other code not governed by the terms of this License and
+ distribute the Larger Work as a single product. In such a case,
+ You must make sure the requirements of this License are fulfilled
+ for the Covered Software.
+
+4. Versions of the License.
+
+ 4.1. New Versions.
+
+ Sun Microsystems, Inc. is the initial license steward and may
+ publish revised and/or new versions of this License from time to
+ time. Each version will be given a distinguishing version number.
+ Except as provided in Section 4.3, no one other than the license
+ steward has the right to modify this License.
+
+ 4.2. Effect of New Versions.
+
+ You may always continue to use, distribute or otherwise make the
+ Covered Software available under the terms of the version of the
+ License under which You originally received the Covered Software.
+ If the Initial Developer includes a notice in the Original
+ Software prohibiting it from being distributed or otherwise made
+ available under any subsequent version of the License, You must
+ distribute and make the Covered Software available under the terms
+ of the version of the License under which You originally received
+ the Covered Software. Otherwise, You may also choose to use,
+ distribute or otherwise make the Covered Software available under
+ the terms of any subsequent version of the License published by
+ the license steward.
+
+ 4.3. Modified Versions.
+
+ When You are an Initial Developer and You want to create a new
+ license for Your Original Software, You may create and use a
+ modified version of this License if You: (a) rename the license
+ and remove any references to the name of the license steward
+ (except to note that the license differs from this License); and
+ (b) otherwise make it clear that the license contains terms which
+ differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
+ BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
+ SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
+ PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
+ PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
+ COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+ INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
+ NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
+ WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
+ DISCLAIMER.
+
+6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to
+ cure such breach within 30 days of becoming aware of the breach.
+ Provisions which, by their nature, must remain in effect beyond
+ the termination of this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding
+ declaratory judgment actions) against Initial Developer or a
+ Contributor (the Initial Developer or Contributor against whom You
+ assert such claim is referred to as "Participant") alleging that
+ the Participant Software (meaning the Contributor Version where
+ the Participant is a Contributor or the Original Software where
+ the Participant is the Initial Developer) directly or indirectly
+ infringes any patent, then any and all rights granted directly or
+ indirectly to You by such Participant, the Initial Developer (if
+ the Initial Developer is not the Participant) and all Contributors
+ under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
+ notice from Participant terminate prospectively and automatically
+ at the expiration of such 60 day notice period, unless if within
+ such 60 day period You withdraw Your claim with respect to the
+ Participant Software against such Participant either unilaterally
+ or pursuant to a written agreement with Participant.
+
+ 6.3. In the event of termination under Sections 6.1 or 6.2 above,
+ all end user licenses that have been validly granted by You or any
+ distributor hereunder prior to termination (excluding licenses
+ granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+ INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
+ COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
+ LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
+ CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+ LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
+ STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+ INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
+ APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
+ NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
+ APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a "commercial item," as that term is
+ defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
+ computer software" (as that term is defined at 48
+ C.F.R. 252.227-7014(a)(1)) and "commercial computer software
+ documentation" as such terms are used in 48 C.F.R. 12.212
+ (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
+ C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
+ U.S. Government End Users acquire Covered Software with only those
+ rights set forth herein. This U.S. Government Rights clause is in
+ lieu of, and supersedes, any other FAR, DFAR, or other clause or
+ provision that addresses Government rights in computer software
+ under this License.
+
+9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed
+ by the law of the jurisdiction specified in a notice contained
+ within the Original Software (except to the extent applicable law,
+ if any, provides otherwise), excluding such jurisdiction's
+ conflict-of-law provisions. Any litigation relating to this
+ License shall be subject to the jurisdiction of the courts located
+ in the jurisdiction and venue specified in a notice contained
+ within the Original Software, with the losing party responsible
+ for costs, including, without limitation, court costs and
+ reasonable attorneys' fees and expenses. The application of the
+ United Nations Convention on Contracts for the International Sale
+ of Goods is expressly excluded. Any law or regulation which
+ provides that the language of a contract shall be construed
+ against the drafter shall not apply to this License. You agree
+ that You alone are responsible for compliance with the United
+ States export administration regulations (and the export control
+ laws and regulation of any other countries) when You use,
+ distribute or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or
+ indirectly, out of its utilization of rights under this License
+ and You agree to work with Initial Developer and Contributors to
+ distribute such responsibility on an equitable basis. Nothing
+ herein is intended or shall be deemed to constitute any admission
+ of liability.
+
--- /dev/null
+#!/usr/bin/make -f
+##########################################################
+# Copyright (C) 2009 VMware, Inc. All rights reserved.
+#
+# The contents of this file are subject to the terms of the Common
+# Development and Distribution License (the "License") version 1.0
+# and no later version. You may not use this file except in
+# compliance with the License.
+#
+# You can obtain a copy of the License at
+# http://www.opensource.org/licenses/cddl1.php
+#
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+##########################################################
+
+##
+## General build locations and variables
+##
+
+MODULE := vmmemctl
+MODULE_32 := i386/$(MODULE)
+MODULE_64 := amd64/$(MODULE)
+
+PROG := vmware-memctld
+PROG_32 := i386/$(PROG)
+PROG_64 := amd64/$(PROG)
+
+CFLAGS :=
+KFLAGS :=
+LDFLAGS :=
+
+CFLAGS += -O
+CFLAGS += -Wall -Wno-unknown-pragmas -Werror
+CFLAGS += -I../../../lib/include # for buildNumber.h
+
+KFLAGS += -D_KERNEL
+
+##
+## Objects needed to build the vmmemctl kernel module
+##
+VMMCTL_OBJS := vmballoon.o
+VMMCTL_OBJS += vmballoon_kstats.o
+VMMCTL_OBJS += os.o
+
+VMMCTL_32_OBJS := $(addprefix i386/, $(VMMCTL_OBJS))
+VMMCTL_32_OBJS += i386/backdoorGcc32.o
+
+VMMCTL_64_OBJS := $(addprefix amd64/, $(VMMCTL_OBJS))
+VMMCTL_64_OBJS += amd64/backdoorGcc64.o
+
+##
+## Objects needed to build the vmware-memctld program
+##
+VMMCTLD_OBJS := vmmemctld.o
+
+VMMCTLD_32_OBJS := $(addprefix i386/, $(VMMCTLD_OBJS))
+VMMCTLD_64_OBJS := $(addprefix amd64/, $(VMMCTLD_OBJS))
+
+
+ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.9) # {
+
+# Solaris 9
+MODULES := $(MODULE_32)
+PROGS := $(PROG_32)
+INSTALL := install32
+CFLAGS += -D__STDC__=0 -DSOL9
+
+else # } {
+ifeq ($(shell echo "$(VM_UNAME)" | cut -c-4),5.10) # {
+
+# Solaris 10
+MODULES := $(MODULE_32) $(MODULE_64)
+PROGS := $(PROG_32) $(PROG_64)
+INSTALL := install32 install64
+CFLAGS += -DSOL10
+KFLAGS += -ffreestanding
+KFLAGS += -nodefaultlibs
+
+else # } {
+
+$(error "This makefile is only used for Solaris 9 and 10")
+
+endif # }
+endif # }
+
+CFLAGS_32 := $(CFLAGS)
+CFLAGS_32 += -m32
+LDFLAGS_32 := $(LDFLAGS)
+
+CFLAGS_64 := $(CFLAGS)
+CFLAGS_64 += -m64
+
+KFLAGS_32 := $(KFLAGS)
+
+KFLAGS_64 := $(KFLAGS)
+KFLAGS_64 += -mcmodel=kernel
+KFLAGS_64 += -mno-red-zone
+
+LDFLAGS_64 := $(LDFLAGS)
+ifdef HAVE_GNU_LD
+LDFLAGS_64 += -m elf_x86_64
+else
+LDFLAGS_64 += -64
+endif
+
+all: prepare_dirs $(MODULES) $(PROGS)
+
+prepare_dirs:
+ @echo "Creating build directories"
+ mkdir -p i386
+ mkdir -p amd64
+
+$(MODULE_32): $(VMMCTL_32_OBJS)
+ @echo "Linking $@"
+ $(LD) $(LDFLAGS_32) -r $(VMMCTL_32_OBJS) -o $@
+
+$(VMMCTL_32_OBJS): i386/%.o: %.c
+ @echo "Compiling $(<F)"
+ $(CC) $(CFLAGS_32) $(KFLAGS_32) -c $< -o $@
+
+$(MODULE_64): $(VMMCTL_64_OBJS)
+ @echo "Linking $@"
+ $(LD) $(LDFLAGS_64) -r $(VMMCTL_64_OBJS) -o $@
+
+$(VMMCTL_64_OBJS): amd64/%.o: %.c
+ @echo "Compiling $(<F)"
+ $(CC) $(CFLAGS_64) $(KFLAGS_64) -c $< -o $@
+
+$(PROG_32): $(VMMCTLD_32_OBJS)
+ @echo "Linking $@"
+ $(CC) -m32 $(VMMCTLD_32_OBJS) -o $@
+
+$(VMMCTLD_32_OBJS): i386/%.o: %.c
+ @echo "Compiling $(<F)"
+ $(CC) $(CFLAGS_32) -c $< -o $@
+
+$(PROG_64): $(VMMCTLD_64_OBJS)
+ @echo "Linking $@"
+ $(CC) -m64 $(VMMCTLD_64_OBJS) $< -o $@
+
+$(VMMCTLD_64_OBJS): amd64/%.o: %.c
+ @echo "Compiling $(<F)"
+ $(CC) $(CFLAGS_64) -c $< -o $@
+
+clean:
+ @echo "Cleaning directories"
+ @rm -rf $(MODULE_32) $(PROG_32) $(VMMCTL_32_OBJS) $(VMMCTLD_32_OBJS) i386
+ @rm -rf $(MODULE_64) $(PROG_64) $(VMMCTL_64_OBJS) $(VMMCTLD_64_OBJS) amd64
+
+install32:
+ cp $(MODULE_32) /kernel/drv/
+ chmod 755 /kernel/drv/$(MODULE)
+ mkdir -p /usr/sbin/i86
+ cp $(PROG_32) /usr/sbin/i86/$(PROG)
+ chmod 755 /usr/sbin/i86/$(PROG)
+ ln -f /usr/lib/isaexec /usr/sbin/$(PROG)
+
+install64:
+ chmod 755 /kernel/drv/$(MODULE)
+ cp $(MODULE_64) /kernel/drv/amd64
+ mkdir -p /usr/sbin/amd64
+ cp $(PROG_64) /usr/sbin/amd64/$(PROG)
+ chmod 755 /usr/sbin/amd64/$(PROG)
+
+install: $(INSTALL)
+ cp vmmemctl.conf /kernel/drv/
+ chmod 755 /kernel/drv/vmmemctl.conf
+ grep $(MODULE) /etc/name_to_major > /dev/null 2>&1; \
+ if [ ! $$? = 0 ]; then \
+ /usr/sbin/add_drv $(MODULE); \
+ fi
--- /dev/null
+The files in this directory are components of the VMware Memory
+Control driver. This version of the driver will only work on an x86
+system running Solaris 9 or later with a 32-bit kernel. This driver
+will be installed by the installer of the VMware Tools for Solaris
+package.
/*********************************************************
* Copyright (C) 1999 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * backdoorGcc32.c --
+ *
+ * Implements the real work for guest-side backdoor for GCC, 32-bit
+ * target (supports inline ASM, GAS syntax). The asm sections are marked
+ * volatile since vmware can change the registers content without the
+ * compiler knowing it.
+ *
+ * XXX
+ * I tried to write this more cleanly, but:
+ * - There is no way to specify an "ebp" constraint
+ * - "ebp" is ignored when specified as cloberred register
+ * - gas barfs when there is more than 10 operands
+ * - gas 2.7.2.3, depending on the order of the operands, can
+ * mis-assemble without any warning
+ * --hpreg
+ *
+ * Note that the problems with gas noted above might longer be relevant
+ * now that we've upgraded most of our compiler versions.
+ * --rrdharan
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "backdoor.h"
+#include "backdoorInt.h"
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * Backdoor_InOut --
+ *
+ * Send a low-bandwidth basic request (16 bytes) to vmware, and return its
+ * reply (24 bytes).
+ *
+ * Results:
+ * Host-side response returned in bp IN/OUT parameter.
+ *
+ * Side effects:
+ * Pokes the backdoor.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT
+{
+ uint32 dummy;
+
+ __asm__ __volatile__(
+#ifdef __PIC__
+ "pushl %%ebx" "\n\t"
+#endif
+ "pushl %%eax" "\n\t"
+ "movl 20(%%eax), %%edi" "\n\t"
+ "movl 16(%%eax), %%esi" "\n\t"
+ "movl 12(%%eax), %%edx" "\n\t"
+ "movl 8(%%eax), %%ecx" "\n\t"
+ "movl 4(%%eax), %%ebx" "\n\t"
+ "movl (%%eax), %%eax" "\n\t"
+ "inl %%dx, %%eax" "\n\t"
+ "xchgl %%eax, (%%esp)" "\n\t"
+ "movl %%edi, 20(%%eax)" "\n\t"
+ "movl %%esi, 16(%%eax)" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "movl %%ebx, 4(%%eax)" "\n\t"
+ "popl (%%eax)" "\n\t"
+#ifdef __PIC__
+ "popl %%ebx" "\n\t"
+#endif
+ : "=a" (dummy)
+ : "0" (myBp)
+ /*
+ * vmware can modify the whole VM state without the compiler knowing
+ * it. So far it does not modify EFLAGS. --hpreg
+ */
+ :
+#ifndef __PIC__
+ "ebx",
+#endif
+ "ecx", "edx", "esi", "edi", "memory"
+ );
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BackdoorHbIn --
+ * BackdoorHbOut --
+ *
+ * Send a high-bandwidth basic request to vmware, and return its
+ * reply.
+ *
+ * Results:
+ * Host-side response returned in bp IN/OUT parameter.
+ *
+ * Side-effects:
+ * Pokes the high-bandwidth backdoor port.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT
+{
+ uint32 dummy;
+
+ __asm__ __volatile__(
+#ifdef __PIC__
+ "pushl %%ebx" "\n\t"
+#endif
+ "pushl %%ebp" "\n\t"
+
+ "pushl %%eax" "\n\t"
+ "movl 24(%%eax), %%ebp" "\n\t"
+ "movl 20(%%eax), %%edi" "\n\t"
+ "movl 16(%%eax), %%esi" "\n\t"
+ "movl 12(%%eax), %%edx" "\n\t"
+ "movl 8(%%eax), %%ecx" "\n\t"
+ "movl 4(%%eax), %%ebx" "\n\t"
+ "movl (%%eax), %%eax" "\n\t"
+ "cld" "\n\t"
+ "rep; insb" "\n\t"
+ "xchgl %%eax, (%%esp)" "\n\t"
+ "movl %%ebp, 24(%%eax)" "\n\t"
+ "movl %%edi, 20(%%eax)" "\n\t"
+ "movl %%esi, 16(%%eax)" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "movl %%ebx, 4(%%eax)" "\n\t"
+ "popl (%%eax)" "\n\t"
+
+ "popl %%ebp" "\n\t"
+#ifdef __PIC__
+ "popl %%ebx" "\n\t"
+#endif
+ : "=a" (dummy)
+ : "0" (myBp)
+ /*
+ * vmware can modify the whole VM state without the compiler knowing
+ * it. --hpreg
+ */
+ :
+#ifndef __PIC__
+ "ebx",
+#endif
+ "ecx", "edx", "esi", "edi", "memory", "cc"
+ );
+}
+
+
+void
+BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT
+{
+ uint32 dummy;
+
+ __asm__ __volatile__(
+#ifdef __PIC__
+ "pushl %%ebx" "\n\t"
+#endif
+ "pushl %%ebp" "\n\t"
+
+ "pushl %%eax" "\n\t"
+ "movl 24(%%eax), %%ebp" "\n\t"
+ "movl 20(%%eax), %%edi" "\n\t"
+ "movl 16(%%eax), %%esi" "\n\t"
+ "movl 12(%%eax), %%edx" "\n\t"
+ "movl 8(%%eax), %%ecx" "\n\t"
+ "movl 4(%%eax), %%ebx" "\n\t"
+ "movl (%%eax), %%eax" "\n\t"
+ "cld" "\n\t"
+ "rep; outsb" "\n\t"
+ "xchgl %%eax, (%%esp)" "\n\t"
+ "movl %%ebp, 24(%%eax)" "\n\t"
+ "movl %%edi, 20(%%eax)" "\n\t"
+ "movl %%esi, 16(%%eax)" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "movl %%ebx, 4(%%eax)" "\n\t"
+ "popl (%%eax)" "\n\t"
+
+ "popl %%ebp" "\n\t"
+#ifdef __PIC__
+ "popl %%ebx" "\n\t"
+#endif
+ : "=a" (dummy)
+ : "0" (myBp)
+ :
+#ifndef __PIC__
+ "ebx",
+#endif
+ "ecx", "edx", "esi", "edi", "memory", "cc"
+ );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * backdoorGcc64.c --
+ *
+ * Implements the real work for guest-side backdoor for GCC, 64-bit
+ * target (supports inline ASM, GAS syntax). The asm sections are marked
+ * volatile since vmware can change the registers content without the
+ * compiler knowing it.
+ *
+ * See backdoorGCC32.c (from which this code was mostly copied) for
+ * details on why the ASM is written this way. Also note that it might be
+ * possible to write the asm blocks using the symbolic operand specifiers
+ * in such a way that the same asm would generate correct code for both
+ * 32-bit and 64-bit targets, but I'm too lazy to figure it all out.
+ * --rrdharan
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "backdoor.h"
+#include "backdoorInt.h"
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * Backdoor_InOut --
+ *
+ * Send a low-bandwidth basic request (16 bytes) to vmware, and return its
+ * reply (24 bytes).
+ *
+ * Results:
+ * Host-side response returned in bp IN/OUT parameter.
+ *
+ * Side effects:
+ * Pokes the backdoor.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT
+{
+ uint64 dummy;
+
+ __asm__ __volatile__(
+ "pushq %%rax" "\n\t"
+ "movq 40(%%rax), %%rdi" "\n\t"
+ "movq 32(%%rax), %%rsi" "\n\t"
+ "movq 24(%%rax), %%rdx" "\n\t"
+ "movq 16(%%rax), %%rcx" "\n\t"
+ "movq 8(%%rax), %%rbx" "\n\t"
+ "movq (%%rax), %%rax" "\n\t"
+ "inl %%dx, %%eax" "\n\t" /* NB: There is no inq instruction */
+ "xchgq %%rax, (%%rsp)" "\n\t"
+ "movq %%rdi, 40(%%rax)" "\n\t"
+ "movq %%rsi, 32(%%rax)" "\n\t"
+ "movq %%rdx, 24(%%rax)" "\n\t"
+ "movq %%rcx, 16(%%rax)" "\n\t"
+ "movq %%rbx, 8(%%rax)" "\n\t"
+ "popq (%%rax)"
+ : "=a" (dummy)
+ : "0" (myBp)
+ /*
+ * vmware can modify the whole VM state without the compiler knowing
+ * it. So far it does not modify EFLAGS. --hpreg
+ */
+ : "rbx", "rcx", "rdx", "rsi", "rdi", "memory"
+ );
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BackdoorHbIn --
+ * BackdoorHbOut --
+ *
+ * Send a high-bandwidth basic request to vmware, and return its
+ * reply.
+ *
+ * Results:
+ * Host-side response returned in bp IN/OUT parameter.
+ *
+ * Side-effects:
+ * Pokes the high-bandwidth backdoor port.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT
+{
+ uint32 dummy;
+
+ __asm__ __volatile__(
+ "pushq %%rbp" "\n\t"
+
+ "pushq %%rax" "\n\t"
+ "movq 48(%%rax), %%rbp" "\n\t"
+ "movq 40(%%rax), %%rdi" "\n\t"
+ "movq 32(%%rax), %%rsi" "\n\t"
+ "movq 24(%%rax), %%rdx" "\n\t"
+ "movq 16(%%rax), %%rcx" "\n\t"
+ "movq 8(%%rax), %%rbx" "\n\t"
+ "movq (%%rax), %%rax" "\n\t"
+ "cld" "\n\t"
+ "rep; insb" "\n\t"
+ "xchgq %%rax, (%%rsp)" "\n\t"
+ "movq %%rbp, 48(%%rax)" "\n\t"
+ "movq %%rdi, 40(%%rax)" "\n\t"
+ "movq %%rsi, 32(%%rax)" "\n\t"
+ "movq %%rdx, 24(%%rax)" "\n\t"
+ "movq %%rcx, 16(%%rax)" "\n\t"
+ "movq %%rbx, 8(%%rax)" "\n\t"
+ "popq (%%rax)" "\n\t"
+
+ "popq %%rbp"
+ : "=a" (dummy)
+ : "0" (myBp)
+ /*
+ * vmware can modify the whole VM state without the compiler knowing
+ * it. --hpreg
+ */
+ : "rbx", "rcx", "rdx", "rsi", "rdi", "memory", "cc"
+ );
+}
+
+
+void
+BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT
+{
+ uint64 dummy;
+
+ __asm__ __volatile__(
+ "pushq %%rbp" "\n\t"
+
+ "pushq %%rax" "\n\t"
+ "movq 48(%%rax), %%rbp" "\n\t"
+ "movq 40(%%rax), %%rdi" "\n\t"
+ "movq 32(%%rax), %%rsi" "\n\t"
+ "movq 24(%%rax), %%rdx" "\n\t"
+ "movq 16(%%rax), %%rcx" "\n\t"
+ "movq 8(%%rax), %%rbx" "\n\t"
+ "movq (%%rax), %%rax" "\n\t"
+ "cld" "\n\t"
+ "rep; outsb" "\n\t"
+ "xchgq %%rax, (%%rsp)" "\n\t"
+ "movq %%rbp, 48(%%rax)" "\n\t"
+ "movq %%rdi, 40(%%rax)" "\n\t"
+ "movq %%rsi, 32(%%rax)" "\n\t"
+ "movq %%rdx, 24(%%rax)" "\n\t"
+ "movq %%rcx, 16(%%rax)" "\n\t"
+ "movq %%rbx, 8(%%rax)" "\n\t"
+ "popq (%%rax)" "\n\t"
+
+ "popq %%rbp"
+ : "=a" (dummy)
+ : "0" (myBp)
+ : "rbx", "rcx", "rdx", "rsi", "rdi", "memory", "cc"
+ );
+}
+
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * backdoorInt.h --
+ *
+ * Internal function prototypes for the real backdoor work.
+ */
+
+void BackdoorHbIn(Backdoor_proto_hb *bp);
+void BackdoorHbOut(Backdoor_proto_hb *bp);
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * backdoor_balloon.h --
+ *
+ * This file provides a wrapper for using the more generic backdoor library
+ * together with the vmballoon-specific backdoor.
+ */
+
+#ifndef _BACKDOOR_BALLOON_H_
+#define _BACKDOOR_BALLOON_H_
+
+#include "backdoor.h"
+#include "balloon_def.h"
+
+static INLINE
+void Backdoor_Balloon(Backdoor_proto *myBp) {
+ myBp->in.ax.word = BALLOON_BDOOR_MAGIC;
+ myBp->in.dx.halfs.low = BALLOON_BDOOR_PORT;
+ Backdoor_InOut(myBp);
+}
+
+#endif /* _BACKDOOR_BALLOON_H_ */
/*********************************************************
* Copyright (C) 1999 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2000 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * balloon_def.h --
+ *
+ * Definitions for server "balloon" mechanism for reclaiming
+ * physical memory from a VM.
+ */
+
+#ifndef _BALLOON_DEF_H
+#define _BALLOON_DEF_H
+
+#define INCLUDE_ALLOW_VMCORE
+#define INCLUDE_ALLOW_VMKERNEL
+#define INCLUDE_ALLOW_MODULE
+#include "includeCheck.h"
+
+#include "vm_basic_types.h"
+
+/*
+ * constants
+ */
+
+/* backdoor port */
+#define BALLOON_BDOOR_PORT (0x5670)
+#define BALLOON_BDOOR_MAGIC (0x456c6d6f)
+
+/* backdoor command numbers */
+#define BALLOON_BDOOR_CMD_START (0)
+#define BALLOON_BDOOR_CMD_TARGET (1)
+#define BALLOON_BDOOR_CMD_LOCK (2)
+#define BALLOON_BDOOR_CMD_UNLOCK (3)
+#define BALLOON_BDOOR_CMD_GUEST_ID (4)
+
+/* use config value for max balloon size */
+#define BALLOON_MAX_SIZE_USE_CONFIG (0)
+
+/* guest identities */
+#define BALLOON_GUEST_UNKNOWN (0)
+#define BALLOON_GUEST_LINUX (1)
+#define BALLOON_GUEST_BSD (2)
+#define BALLOON_GUEST_WINDOWS_NT4 (3)
+#define BALLOON_GUEST_WINDOWS_NT5 (4)
+#define BALLOON_GUEST_SOLARIS (5)
+
+/* error codes */
+#define BALLOON_SUCCESS (0)
+#define BALLOON_FAILURE (-1)
+#define BALLOON_ERROR_CMD_INVALID (1)
+#define BALLOON_ERROR_PPN_INVALID (2)
+#define BALLOON_ERROR_PPN_LOCKED (3)
+#define BALLOON_ERROR_PPN_UNLOCKED (4)
+#define BALLOON_ERROR_PPN_PINNED (5)
+#define BALLOON_ERROR_PPN_NOTNEEDED (6)
+#define BALLOON_ERROR_RESET (7)
+#define BALLOON_ERROR_BUSY (8)
+
+#endif /* _BALLOON_DEF_H */
/*********************************************************
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * os.c --
+ *
+ * Wrappers for Solaris system functions required by "vmmemctl".
+ */
+
+/*
+ * Includes
+ */
+#include <sys/types.h>
+#include <sys/cred.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/conf.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/modctl.h>
+#include <sys/stat.h>
+#include <sys/kstat.h>
+#include <sys/id_space.h>
+#include <sys/vnode.h>
+#include <sys/taskq.h>
+#include <sys/disp.h>
+#include <sys/ksynch.h>
+
+#include "os.h"
+#include "balloon_def.h"
+#include "vmballoon_kstats.h"
+#include "vmmemctl.h"
+#include "buildNumber.h"
+
+#if defined(SOL9)
+extern unsigned disable_memscrub;
+#else
+extern void memscrub_disable(void);
+#endif
+
+/*
+ * Constants
+ */
+
+#define ONE_SECOND_IN_MICROSECONDS 1000000
+
+/*
+ * Types
+ */
+
+typedef struct {
+ timeout_id_t id;
+
+ /* termination flag */
+ volatile int stop;
+
+ /* synchronization with worker thread */
+ kmutex_t lock;
+ kcondvar_t cv;
+
+ /* registered state */
+ os_timer_handler handler;
+ void *data;
+ int period;
+} os_timer;
+
+/*
+ * Keep track of offset here rather than peeking inside the page_t to
+ * avoid dependencies on the page structure layout (which changes from
+ * release to release).
+ */
+typedef struct {
+ page_t *pp;
+ u_offset_t offset;
+} os_page;
+
+typedef struct {
+ const char *name;
+ const char *name_verbose;
+ os_timer timer;
+ kstat_t *kstats;
+ id_space_t *id_space;
+ vnode_t vnode;
+} os_state;
+
+/*
+ * Globals
+ */
+
+static os_state global_state;
+static dev_info_t *vmmemctl_dip; /* only one instance */
+
+/*
+ * Simple Wrappers
+ */
+
+void *os_kmalloc_nosleep(unsigned int size)
+{
+ return (kmem_alloc(size, KM_NOSLEEP));
+}
+
+void os_kfree(void *obj, unsigned int size)
+{
+ kmem_free(obj, size);
+}
+
+void os_bzero(void *b, unsigned int len)
+{
+ bzero(b, len);
+}
+
+void os_memcpy(void *dest, const void *src, unsigned int size)
+{
+ bcopy(src, dest, size);
+}
+
+int os_sprintf(char *str, const char *format, ...)
+{
+ ASSERT(0);
+ /*
+ * XXX disabled because the varargs header file doesn't seem to
+ * work in the current (gcc 2.95.3) cross-compiler environment.
+ * Not used for Solaris anyway.
+ */
+ return 0;
+}
+
+/*
+ * System-Dependent Operations
+ */
+
+char *os_identity(void)
+{
+ return "solaris";
+}
+
+/*
+ * Predict the maximum achievable balloon size.
+ *
+ * Currently we just return the total memory pages.
+ */
+unsigned int os_predict_max_balloon_pages(void)
+{
+ return(maxmem);
+}
+
+unsigned long os_addr_to_ppn(unsigned long addr)
+{
+ return (ulong_t)page_pptonum(((os_page *)addr)->pp);
+}
+
+/*
+ * NOTE: cast id before shifting to avoid overflow (id_t is 32 bits,
+ * u_offset_t is 64 bits). Also, can't use ptob because it will
+ * overflow in a 32-bit kernel (since ptob returns a ulong_t, and the
+ * physical address may be larger than 2^32).
+ */
+#define idtooff(id) ((u_offset_t)(id) << PAGESHIFT)
+#define offtoid(off) ((id_t)((off) >> PAGESHIFT))
+
+/*
+ * This is a bit ugly. In order to allocate a page, we need a vnode to
+ * hang it from and a unique offset within that vnode. We do this by
+ * using our own vnode (used only to hang pages from) and allocating
+ * offsets by use of the id space allocator. The id allocator hands
+ * us back unique integers between 0 and INT_MAX; we can then use those
+ * as page indices into our fake vnode space.
+ *
+ * Future versions of Solaris will have a devmap_pmem_alloc/free
+ * interface for allocating physical pages that may allow us to
+ * eliminate some of this.
+ */
+unsigned long os_alloc_reserved_page(int can_sleep)
+{
+ os_state *state = &global_state;
+ page_t *pp;
+ u_offset_t off;
+ struct seg kseg;
+ os_page *page;
+ id_space_t *idp = state->id_space;
+ vnode_t *vp = &state->vnode;
+ uint_t flags;
+
+ /*
+ * Reserve space for the page.
+ */
+ flags = can_sleep ? KM_SLEEP : KM_NOSLEEP;
+ if (!page_resv(1, flags))
+ return 0; /* no space! */
+
+ /*
+ * Allocating space for os_page early simplifies error handling.
+ */
+ if ((page = kmem_alloc(sizeof (os_page), flags)) == NULL) {
+ page_unresv(1);
+ return 0;
+ }
+
+ /*
+ * Construct an offset for page_create.
+ */
+ off = idtooff(id_alloc(idp));
+
+ /*
+ * Allocate the page itself. Note that this can fail.
+ */
+ kseg.s_as = &kas;
+ flags = can_sleep ? PG_EXCL | PG_WAIT : PG_EXCL;
+ pp = page_create_va(vp, off, PAGESIZE, flags, &kseg,
+ (caddr_t)(ulong_t)off);
+ if (pp != NULL) {
+ /*
+ * We got a page. We keep the PG_EXCL lock to prohibit
+ * anyone (swrand, memscrubber) touching the page. Return the
+ * pointer to structure describing page.
+ */
+ page_io_unlock(pp);
+ page_hashout(pp, NULL);
+ page->pp = pp;
+ page->offset = off;
+ } else {
+ /*
+ * Oops, didn't get a page. Undo everything and return.
+ */
+ id_free(idp, offtoid(off));
+ kmem_free(page, sizeof (os_page));
+ page_unresv(1);
+ page = NULL;
+ }
+
+ return (unsigned long)page;
+}
+
+void os_free_reserved_page(unsigned long addr)
+{
+ os_state *state = &global_state;
+ os_page *page = (os_page *)addr;
+ page_t *pp = page->pp;
+ u_offset_t off = page->offset;
+ id_space_t *idp = state->id_space;
+
+ page_free(pp, 1);
+ page_unresv(1);
+ id_free(idp, offtoid(off));
+ kmem_free(page, sizeof (os_page));
+}
+
+/*
+ * Worker thread that periodically calls the timer handler. This is
+ * executed by a user context thread so that it can block waiting for
+ * memory without fear of deadlock.
+ */
+static int os_worker(void)
+{
+ os_timer *t = &global_state.timer;
+ clock_t timeout;
+
+ mutex_enter(&t->lock);
+ while (!t->stop) {
+ /* invoke registered handler */
+ mutex_exit(&t->lock);
+ (void) (*(t->handler))(t->data);
+ mutex_enter(&t->lock);
+
+ /* check again whether we should stop */
+ if (t->stop)
+ break;
+
+ /* wait for timeout */
+ (void) drv_getparm(LBOLT, &timeout);
+ timeout += t->period;
+ if (cv_timedwait_sig(&t->cv, &t->lock, timeout) == 0) {
+ mutex_exit(&t->lock);
+ return EINTR; /* took a signal, return to user level */
+ }
+ }
+ mutex_exit(&t->lock);
+ ASSERT(t->stop);
+ return 0; /* normal termination */
+}
+
+/*
+ * Initialize timer data.
+ */
+void os_timer_init(os_timer_handler handler, void *data, int period)
+{
+ os_timer *t = &global_state.timer;
+
+ t->id = 0;
+ t->handler = handler;
+ t->data = data;
+ t->period = period;
+ t->stop = 0;
+
+ mutex_init(&t->lock, NULL, MUTEX_DRIVER, NULL);
+ cv_init(&t->cv, NULL, CV_DRIVER, NULL);
+}
+
+void os_timer_start(void)
+{
+ os_timer *t = &global_state.timer;
+
+ t->stop = 0;
+}
+
+void os_timer_stop(void)
+{
+ os_timer *t = &global_state.timer;
+
+ mutex_enter(&t->lock);
+
+ /* set termination flag */
+ t->stop = 1;
+
+ /* wake up worker thread so it can exit */
+ cv_signal(&t->cv);
+
+ mutex_exit(&t->lock);
+}
+
+static void os_timer_cleanup(void)
+{
+ os_timer *timer = &global_state.timer;
+
+ mutex_destroy(&timer->lock);
+ cv_destroy(&timer->cv);
+}
+
+unsigned int os_timer_hz(void)
+{
+ return drv_usectohz(ONE_SECOND_IN_MICROSECONDS);
+}
+
+void os_yield(void)
+{
+ /* Do nothing. */
+}
+
+void os_init(const char *name,
+ const char *name_verbose,
+ os_status_handler handler)
+{
+ os_state *state = &global_state;
+ static int initialized = 0;
+
+ /* initialize only once */
+ if (initialized++) {
+ return;
+ }
+
+ /* zero global state */
+ bzero(state, sizeof(global_state));
+
+ state->kstats = BalloonKstatCreate();
+ state->id_space = id_space_create("vmmemctl", 0, INT_MAX);
+ state->name = name;
+ state->name_verbose = name_verbose;
+
+ /* disable memscrubber */
+#if defined(SOL9)
+ disable_memscrub = 1;
+#else
+ memscrub_disable();
+#endif
+
+ /* log device load */
+ cmn_err(CE_CONT, "!%s initialized\n", name_verbose);
+}
+
+void os_cleanup(void)
+{
+ os_state *state = &global_state;
+
+ os_timer_cleanup();
+ BalloonKstatDelete(state->kstats);
+ id_space_destroy(state->id_space);
+
+ /* log device unload */
+ cmn_err(CE_CONT, "!%s unloaded\n", state->name_verbose);
+}
+
+/*
+ * Module Load/Unload Operations
+ */
+
+extern int init_module(void);
+extern void cleanup_module(void);
+
+/*
+ * Device configuration entry points
+ */
+static int vmmemctl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
+{
+ switch (cmd) {
+ case DDI_ATTACH:
+ vmmemctl_dip = dip;
+ if (ddi_create_minor_node(dip, "0", S_IFCHR, ddi_get_instance(dip),
+ DDI_PSEUDO,0) != DDI_SUCCESS) {
+ return DDI_FAILURE;
+ } else {
+ return DDI_SUCCESS;
+ }
+ default:
+ return DDI_FAILURE;
+ }
+}
+
+static int vmmemctl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
+{
+ switch (cmd) {
+ case DDI_DETACH:
+ vmmemctl_dip = 0;
+ ddi_remove_minor_node(dip, NULL);
+ return DDI_SUCCESS;
+ default:
+ return DDI_FAILURE;
+ }
+}
+
+/*
+ * Commands used by the user level daemon to control the driver.
+ * Since the daemon is single threaded, we use a simple monitor to
+ * make sure that only one thread is executing here at a time.
+ */
+static int vmmemctl_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
+ cred_t *cred, int *rvalp)
+{
+ int error = 0;
+ static int busy = 0; /* set when a thread is in this function */
+ static kmutex_t lock; /* lock to protect busy count */
+
+ if (drv_priv(cred) != 0)
+ return EPERM;
+
+ mutex_enter(&lock);
+ if (busy) {
+ /*
+ * Only one thread at a time.
+ */
+ mutex_exit(&lock);
+ return EBUSY;
+ }
+ busy = 1;
+ mutex_exit(&lock);
+
+ switch (cmd) {
+ case VMMIOCWORK:
+ error = os_worker();
+ break;
+
+ default:
+ error = ENXIO;
+ break;
+ }
+
+ mutex_enter(&lock);
+ ASSERT(busy);
+ busy = 0;
+ mutex_exit(&lock);
+
+ return error;
+}
+
+/*
+ * Module linkage
+ */
+
+static struct cb_ops vmmemctl_cb_ops = {
+ nulldev, /* open */
+ nulldev, /* close */
+ nodev, /* strategy */
+ nodev, /* print */
+ nodev, /* dump */
+ nodev, /* read */
+ nodev, /* write */
+ vmmemctl_ioctl,
+ nodev, /* devmap */
+ nodev, /* mmap */
+ nodev, /* segmap */
+ nochpoll, /* poll */
+ ddi_prop_op, /* prop_op */
+ 0, /* streamtab */
+ D_NEW | D_MP
+};
+
+static struct dev_ops vmmemctl_dev_ops = {
+ DEVO_REV,
+ 0,
+ ddi_no_info, /* getinfo */
+ nulldev, /* identify */
+ nulldev, /* probe */
+ vmmemctl_attach,
+ vmmemctl_detach,
+ nodev, /* reset */
+ &vmmemctl_cb_ops, /* cb_ops */
+ NULL, /* bus_ops */
+ nodev /* power */
+};
+
+static struct modldrv vmmodldrv = {
+ &mod_driverops,
+ "VMware Memory Control b" BUILD_NUMBER_NUMERIC_STRING,
+ &vmmemctl_dev_ops
+};
+
+static struct modlinkage vmmodlinkage = {
+ MODREV_1,
+ {&vmmodldrv, NULL}
+};
+
+int _init(void)
+{
+ int error;
+
+ if (init_module() != BALLOON_SUCCESS)
+ return EINVAL;
+ if ((error = mod_install(&vmmodlinkage)) != 0)
+ cleanup_module();
+ return error;
+}
+
+int _info(struct modinfo *modinfop)
+{
+ return mod_info(&vmmodlinkage, modinfop);
+}
+
+int _fini(void)
+{
+ int error;
+
+ /*
+ * Check if the module is busy (i.e., there's a worker thread active)
+ * before cleaning up.
+ */
+ if ((error = mod_remove(&vmmodlinkage)) == 0)
+ cleanup_module();
+ return error;
+}
+
+
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2000 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * os.h --
+ *
+ * Definitions for OS-specific wrapper functions required
+ * by "vmmemctl". This allows customers to build their own
+ * vmmemctl driver for custom versioned kernels without the
+ * need for source code.
+ */
+
+#ifndef OS_H
+#define OS_H
+
+/*
+ * Needs fixing for 64bit OSes
+ */
+#ifndef __x86_64__
+#define CDECL __attribute__((cdecl, regparm(0)))
+#else
+#define CDECL
+#endif
+
+/*
+ * Types
+ */
+
+typedef void CDECL (*os_timer_handler)(void *);
+typedef int CDECL (*os_status_handler)(char *);
+
+/*
+ * Operations
+ */
+
+extern void CDECL *os_kmalloc_nosleep(unsigned int size);
+extern void CDECL os_kfree(void *obj, unsigned int size);
+extern void CDECL os_yield(void);
+extern void CDECL os_bzero(void *s, unsigned int n);
+extern void CDECL os_memcpy(void *dest, const void *src, unsigned int size);
+extern int CDECL os_sprintf(char *str, const char *format, ...);
+
+extern unsigned long CDECL os_addr_to_ppn(unsigned long addr);
+extern unsigned long CDECL os_alloc_reserved_page(int can_sleep);
+extern void CDECL os_free_reserved_page(unsigned long page);
+
+extern void CDECL os_timer_init(os_timer_handler handler, void *data, int period);
+extern void CDECL os_timer_start(void);
+extern void CDECL os_timer_stop(void);
+
+extern void CDECL os_init(const char *name,
+ const char *name_verbose,
+ os_status_handler handler);
+extern void CDECL os_cleanup(void);
+
+extern char CDECL *os_identity(void);
+
+extern unsigned int CDECL os_predict_max_balloon_pages(void);
+
+extern unsigned int CDECL os_timer_hz(void);
+
+#endif /* OS_H */
/*********************************************************
* Copyright (C) 1998-2004 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
/*********************************************************
* Copyright (C) 2003 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
#elif defined(__APPLE__) && defined(KERNEL)
+#include "availabilityMacOS.h"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// The Mac OS 10.5 kernel SDK defines va_copy in stdarg.h.
+#include <stdarg.h>
+#else
/*
- * MacOS kernel-mode needs va_copy. Based on inspection of stdarg.h
- * from the MacOSX10.4u.sdk kernel framework, this should work.
- * (Future versions of the SDK may break this).
+ * The Mac OS 10.4 kernel SDK needs va_copy. Based on inspection of
+ * stdarg.h from the MacOSX10.4u.sdk kernel framework, this should
+ * work.
*/
-
#define va_copy(dest, src) ((dest) = (src))
+#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#elif defined(__GNUC__) && (__GNUC__ < 3)
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
*********************************************************/
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2000 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * vmballoon.c --
+ *
+ * VMware server physical memory management driver for Unix-ish
+ * (Linux, FreeBSD, Solaris) guests. The driver acts like a
+ * "balloon" that can be inflated to reclaim physical pages by
+ * reserving them in the guest and invalidating them in the
+ * monitor, freeing up the underlying machine pages so they can
+ * be allocated to other guests. The balloon can also be
+ * deflated to allow the guest to use more physical memory.
+ * Higher level policies can control the sizes of balloons in VMs
+ * in order to manage physical memory resources.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Compile-Time Options
+ */
+
+#define BALLOON_RATE_ADAPT (1)
+
+#define BALLOON_DEBUG (1)
+#define BALLOON_DEBUG_VERBOSE (0)
+
+#define BALLOON_STATS
+#define BALLOON_STATS_PROCFS
+
+/*
+ * Includes
+ */
+
+#include "balloon_def.h"
+#include "os.h"
+#include "backdoor.h"
+#include "backdoor_balloon.h"
+
+#include "vmballoon.h"
+
+/*
+ * Constants
+ */
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define BALLOON_NAME "vmmemctl"
+#define BALLOON_NAME_VERBOSE "VMware memory control driver"
+
+#define BALLOON_PROTOCOL_VERSION (2)
+
+#define BALLOON_CHUNK_PAGES (1000)
+
+#define BALLOON_NOSLEEP_ALLOC_MAX (16384)
+
+#define BALLOON_RATE_ALLOC_MIN (512)
+#define BALLOON_RATE_ALLOC_MAX (2048)
+#define BALLOON_RATE_ALLOC_INC (16)
+
+#define BALLOON_RATE_FREE_MIN (512)
+#define BALLOON_RATE_FREE_MAX (16384)
+#define BALLOON_RATE_FREE_INC (16)
+
+#define BALLOON_ERROR_PAGES (16)
+
+/*
+ * When guest is under memory pressure, use a reduced page allocation
+ * rate for next several cycles.
+ */
+#define SLOW_PAGE_ALLOCATION_CYCLES (4)
+
+/*
+ * Move it to bora/public/balloon_def.h later, if needed. Note that
+ * BALLOON_PAGE_ALLOC_FAILURE is an internal error code used for
+ * distinguishing page allocation failures from monitor-backdoor errors.
+ * We use value 1000 because all monitor-backdoor error codes are < 1000.
+ */
+#define BALLOON_PAGE_ALLOC_FAILURE (1000)
+
+// Maximum number of page allocations without yielding processor
+#define BALLOON_ALLOC_YIELD_THRESHOLD (1024)
+
+
+/*
+ * Types
+ */
+
+typedef struct BalloonChunk {
+ unsigned long page[BALLOON_CHUNK_PAGES];
+ uint32 nextPage;
+ struct BalloonChunk *prev, *next;
+} BalloonChunk;
+
+typedef struct {
+ unsigned long page[BALLOON_ERROR_PAGES];
+ uint32 nextPage;
+} BalloonErrorPages;
+
+typedef struct {
+ /* sets of reserved physical pages */
+ BalloonChunk *chunks;
+ int nChunks;
+
+ /* transient list of non-balloonable pages */
+ BalloonErrorPages errors;
+
+ /* balloon size */
+ int nPages;
+ int nPagesTarget;
+
+ /* reset flag */
+ int resetFlag;
+
+ /* adjustment rates (pages per second) */
+ int rateAlloc;
+ int rateFree;
+
+ /* slowdown page allocations for next few cycles */
+ int slowPageAllocationCycles;
+
+ /* statistics */
+ BalloonStats stats;
+} Balloon;
+
+/*
+ * Globals
+ */
+
+static Balloon globalBalloon;
+
+/*
+ * Forward Declarations
+ */
+
+static int BalloonGuestType(void);
+
+static unsigned long BalloonPrimAllocPage(BalloonPageAllocType canSleep);
+static void BalloonPrimFreePage(unsigned long page);
+
+static int Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType);
+static int Balloon_FreePage(Balloon *b, int monitorUnlock);
+static int Balloon_AdjustSize(Balloon *b, uint32 target);
+static void Balloon_Reset(Balloon *b);
+
+static void Balloon_StartTimer(Balloon *b);
+static void Balloon_StopTimer(Balloon *b);
+static void CDECL Balloon_BH(void *data);
+
+static int Balloon_MonitorStart(Balloon *b);
+static int Balloon_MonitorGuestType(Balloon *b);
+static int Balloon_MonitorGetTarget(Balloon *b, uint32 *nPages);
+static int Balloon_MonitorLockPage(Balloon *b, unsigned long addr);
+static int Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr);
+
+/*
+ * Macros
+ */
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifdef BALLOON_STATS
+#define STATS_INC(stat) (stat)++
+#else
+#define STATS_INC(stat)
+#endif
+
+/*
+ * Macros to generate operations for simple lists of OBJ.
+ * OBJ must contain next and prev fields.
+ *
+ */
+
+#define GENERATE_LIST_INSERT(OBJ) \
+static void OBJ ## _Insert(OBJ **head, OBJ *obj) \
+{ \
+ OBJ *h = *head; \
+ \
+ /* add element to head of list */ \
+ obj->next = h; \
+ if (h != NULL) { \
+ h->prev = obj; \
+ } \
+ *head = obj; \
+ obj->prev = NULL; \
+}
+
+#define GENERATE_LIST_REMOVE(OBJ) \
+static void OBJ ## _Remove(OBJ **head, OBJ *obj) \
+{ \
+ /* splice element out of list */ \
+ if (obj->prev != NULL) { \
+ obj->prev->next = obj->next; \
+ } else { \
+ *head = obj->next; \
+ } \
+ if (obj->next != NULL) { \
+ obj->next->prev = obj->prev; \
+ } \
+}
+
+/*
+ * List Operations
+ */
+
+GENERATE_LIST_INSERT(BalloonChunk);
+GENERATE_LIST_REMOVE(BalloonChunk);
+
+/*
+ * Procfs Operations
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonProcRead --
+ *
+ * Ballon driver status reporting routine. Note that this is only
+ * used for Linux.
+ *
+ * Results:
+ * Writes ASCII status information into "buf".
+ * Returns number of bytes written.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int CDECL
+BalloonProcRead(char *buf)
+{
+ int len = 0;
+ BalloonStats stats;
+
+ BalloonGetStats(&stats);
+
+ /* format size info */
+ len += os_sprintf(buf + len,
+ "target: %8d pages\n"
+ "current: %8d pages\n",
+ stats.nPagesTarget,
+ stats.nPages);
+
+ /* format rate info */
+ len += os_sprintf(buf + len,
+ "rateNoSleepAlloc: %8d pages/sec\n"
+ "rateSleepAlloc: %8d pages/sec\n"
+ "rateFree: %8d pages/sec\n",
+ BALLOON_NOSLEEP_ALLOC_MAX,
+ stats.rateAlloc,
+ stats.rateFree);
+
+#ifdef BALLOON_STATS_PROCFS
+ len += os_sprintf(buf + len,
+ "\n"
+ "timer: %8u\n"
+ "start: %8u (%4u failed)\n"
+ "guestType: %8u (%4u failed)\n"
+ "lock: %8u (%4u failed)\n"
+ "unlock: %8u (%4u failed)\n"
+ "target: %8u (%4u failed)\n"
+ "primNoSleepAlloc: %8u (%4u failed)\n"
+ "primCanSleepAlloc: %8u (%4u failed)\n"
+ "primFree: %8u\n"
+ "errAlloc: %8u\n"
+ "errFree: %8u\n",
+ stats.timer,
+ stats.start, stats.startFail,
+ stats.guestType, stats.guestTypeFail,
+ stats.lock, stats.lockFail,
+ stats.unlock, stats.unlockFail,
+ stats.target, stats.targetFail,
+ stats.primAlloc[BALLOON_PAGE_ALLOC_NOSLEEP],
+ stats.primAllocFail[BALLOON_PAGE_ALLOC_NOSLEEP],
+ stats.primAlloc[BALLOON_PAGE_ALLOC_CANSLEEP],
+ stats.primAllocFail[BALLOON_PAGE_ALLOC_CANSLEEP],
+ stats.primFree,
+ stats.primErrorPageAlloc,
+ stats.primErrorPageFree);
+#endif
+
+ return(len);
+}
+
+/*
+ * Utility Operations
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AddrToPPN --
+ *
+ * Return the physical page number corresponding to the specified
+ * Linux kernel-mapped address.
+ *
+ * Results:
+ * Returns PPN for "addr".
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static inline unsigned long
+AddrToPPN(unsigned long addr)
+{
+ return(os_addr_to_ppn(addr));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonPrimAllocPage --
+ *
+ * Attempts to allocate and reserve a physical page.
+ *
+ * If canSleep == 1, i.e., BALLOON_PAGE_ALLOC_CANSLEEP:
+ * The allocation can wait (sleep) for page writeout (swap)
+ * by the guest.
+ * otherwise canSleep == 0, i.e., BALLOON_PAGE_ALLOC_NOSLEEP:
+ * If allocation of a page requires disk writeout, then
+ * just fail. DON'T sleep.
+ *
+ * Results:
+ * Returns the physical address of the allocated page, or 0 if error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static unsigned long
+BalloonPrimAllocPage(BalloonPageAllocType canSleep)
+{
+ return(os_alloc_reserved_page(canSleep));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonPrimFreePage --
+ *
+ * Unreserves and deallocates specified physical page.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+BalloonPrimFreePage(unsigned long page)
+{
+ return(os_free_reserved_page(page));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonGuestType --
+ *
+ * Return balloon guest OS identifier obtained by parsing
+ * system-dependent identity string.
+ *
+ * Results:
+ * Returns one of BALLOON_GUEST_{LINUX,BSD,SOLARIS,UNKNOWN}.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+BalloonGuestType(void)
+{
+ char *identity;
+
+ /* obtain OS identify string */
+ identity = os_identity();
+
+ /* unknown if not specified */
+ if (identity == NULL) {
+ return(BALLOON_GUEST_UNKNOWN);
+ }
+
+ /* classify based on first letter (avoid defining strcmp) */
+ switch (identity[0]) {
+ case 'l':
+ case 'L':
+ return(BALLOON_GUEST_LINUX);
+ case 'b':
+ case 'B':
+ return(BALLOON_GUEST_BSD);
+ case 's':
+ case 'S':
+ return(BALLOON_GUEST_SOLARIS);
+ default:
+ break;
+ }
+
+ /* unknown */
+ return(BALLOON_GUEST_UNKNOWN);
+}
+
+/*
+ * Returns information about balloon state, including the current and
+ * target size, rates for allocating and freeing pages, and statistics
+ * about past activity.
+ */
+void BalloonGetStats(BalloonStats *stats)
+{
+ Balloon *b = &globalBalloon;
+
+ /*
+ * Copy statistics out of global structure.
+ */
+ os_memcpy(stats, &b->stats, sizeof (BalloonStats));
+
+ /*
+ * Fill in additional information about size and rates, which is
+ * normally kept in the Balloon structure itself.
+ */
+ stats->nPages = b->nPages;
+ stats->nPagesTarget = b->nPagesTarget;
+ stats->rateAlloc = b->rateAlloc;
+ stats->rateFree = b->rateFree;
+}
+
+/*
+ * BalloonChunk Operations
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonChunk_Create --
+ *
+ * Creates a new BalloonChunk object capable of tracking
+ * BALLOON_CHUNK_PAGES PPNs.
+ *
+ * We do not bother to define two versions (NOSLEEP and CANSLEEP)
+ * of os_kmalloc because Chunk_Create does not require a new page
+ * often.
+ *
+ * Results:
+ * Returns initialized BalloonChunk, or NULL if error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static BalloonChunk *
+BalloonChunk_Create(void)
+{
+ BalloonChunk *chunk;
+
+ /* allocate memory, fail if unable */
+ if ((chunk = (BalloonChunk *) os_kmalloc_nosleep(sizeof(BalloonChunk))) == NULL) {
+ return(NULL);
+ }
+
+ /* initialize */
+ os_bzero(chunk, sizeof(BalloonChunk));
+
+ /* everything OK */
+ return(chunk);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonChunk_Destroy --
+ *
+ * Reclaims all storage associated with specified BalloonChunk.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+BalloonChunk_Destroy(BalloonChunk *chunk)
+{
+ /* reclaim storage */
+ os_kfree(chunk, sizeof (BalloonChunk));
+}
+
+/*
+ * Balloon operations
+ */
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_Init --
+ *
+ * Initializes device state for balloon "b".
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_Init(Balloon *b)
+{
+ /* clear state */
+ os_bzero(b, sizeof(Balloon));
+
+ /* initialize rates */
+ b->rateAlloc = BALLOON_RATE_ALLOC_MAX;
+ b->rateFree = BALLOON_RATE_FREE_MAX;
+
+ /* initialize reset flag */
+ b->resetFlag = 1;
+
+ /* everything OK */
+ return(BALLOON_SUCCESS);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_Deallocate --
+ *
+ * Frees all allocated pages.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+Balloon_Deallocate(Balloon *b)
+{
+ unsigned int cnt = 0;
+
+ /* free all pages, skipping monitor unlock */
+ while (b->nChunks > 0) {
+ (void) Balloon_FreePage(b, FALSE);
+ if (++cnt >= b->rateFree) {
+ cnt = 0;
+ os_yield();
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_Reset --
+ *
+ * Resets balloon "b" to empty state. Frees all allocated pages
+ * and attempts to reset contact with the monitor.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Schedules next execution of balloon timer handler.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+Balloon_Reset(Balloon *b)
+{
+ uint32 status;
+
+ /* free all pages, skipping monitor unlock */
+ Balloon_Deallocate(b);
+
+ /* send start command */
+ status = Balloon_MonitorStart(b);
+ if (status == BALLOON_SUCCESS) {
+ /* clear flag */
+ b->resetFlag = 0;
+
+ /* report guest type */
+ (void) Balloon_MonitorGuestType(b);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_BH --
+ *
+ * Balloon bottom half handler. Contacts monitor via backdoor
+ * to obtain balloon size target, and starts adjusting balloon
+ * size to achieve target by allocating or deallocating pages.
+ * Resets balloon if requested by the monitor.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Schedules next execution of balloon timer handler.
+ *
+ *----------------------------------------------------------------------
+ */
+static void CDECL
+Balloon_BH(void *data)
+{
+ Balloon *b = (Balloon *) data;
+ uint32 target;
+ int status;
+
+ /* update stats */
+ STATS_INC(b->stats.timer);
+
+ /* reset, if specified */
+ if (b->resetFlag) {
+ Balloon_Reset(b);
+ }
+
+ /* contact monitor via backdoor */
+ status = Balloon_MonitorGetTarget(b, &target);
+
+ /* decrement slowPageAllocationCycles counter */
+ if (b->slowPageAllocationCycles > 0) {
+ b->slowPageAllocationCycles--;
+ }
+
+ if (status == BALLOON_SUCCESS) {
+ /* update target, adjust size */
+ b->nPagesTarget = target;
+ (void) Balloon_AdjustSize(b, target);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_StartTimer --
+ *
+ * Schedules next execution of balloon timer handler.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+Balloon_StartTimer(Balloon *b)
+{
+ os_timer_start();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_StopTimer --
+ *
+ * Deschedules balloon timer handler.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+Balloon_StopTimer(Balloon *b)
+{
+ os_timer_stop();
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ErrorPagesAlloc --
+ *
+ * Attempt to add "page" to list of non-balloonable pages
+ * associated with "b".
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS iff successful, or BALLOON_FAILURE
+ * if non-balloonable page list is already full.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_ErrorPagesAlloc(Balloon *b, unsigned long page)
+{
+ /* fail if list already full */
+ if (b->errors.nextPage >= BALLOON_ERROR_PAGES) {
+ return(BALLOON_FAILURE);
+ }
+
+ /* add page to list */
+ b->errors.page[b->errors.nextPage] = page;
+ b->errors.nextPage++;
+ STATS_INC(b->stats.primErrorPageAlloc);
+ return(BALLOON_SUCCESS);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_ErrorPagesFree --
+ *
+ * Deallocates all pages on the list of non-balloonable pages
+ * associated with "b".
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+Balloon_ErrorPagesFree(Balloon *b)
+{
+ int i;
+
+ /* free all non-balloonable "error" pages */
+ for (i = 0; i < b->errors.nextPage; i++) {
+ BalloonPrimFreePage(b->errors.page[i]);
+ b->errors.page[i] = 0;
+ STATS_INC(b->stats.primErrorPageFree);
+ }
+ b->errors.nextPage = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_AllocPage --
+ *
+ * Attempts to allocate a physical page, inflating balloon "b".
+ * Informs monitor of PPN for allocated page via backdoor.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_AllocPage(Balloon *b, BalloonPageAllocType allocType)
+{
+ BalloonChunk *chunk;
+ unsigned long page;
+ int status;
+
+ retry:
+
+ /* allocate page, fail if unable */
+ STATS_INC(b->stats.primAlloc[allocType]);
+
+ page = BalloonPrimAllocPage(allocType);
+
+ if (page == 0) {
+ STATS_INC(b->stats.primAllocFail[allocType]);
+ return(BALLOON_PAGE_ALLOC_FAILURE);
+ }
+
+ /* find chunk with space, create if necessary */
+ chunk = b->chunks;
+ if ((chunk == NULL) || (chunk->nextPage >= BALLOON_CHUNK_PAGES)) {
+ /* create new chunk */
+ if ((chunk = BalloonChunk_Create()) == NULL) {
+ /* reclaim storage, fail */
+ BalloonPrimFreePage(page);
+ return(BALLOON_PAGE_ALLOC_FAILURE);
+ }
+ BalloonChunk_Insert(&b->chunks, chunk);
+
+ /* update stats */
+ b->nChunks++;
+ }
+
+ /* inform monitor via backdoor */
+ status = Balloon_MonitorLockPage(b, page);
+ if (status != BALLOON_SUCCESS) {
+ /* place on list of non-balloonable pages, retry allocation */
+ if ((status != BALLOON_ERROR_RESET) &&
+ (Balloon_ErrorPagesAlloc(b, page) == BALLOON_SUCCESS)) {
+ goto retry;
+ }
+
+ /* reclaim storage, fail */
+ BalloonPrimFreePage(page);
+ return(status);
+ }
+
+ /* track allocated page */
+ chunk->page[chunk->nextPage] = page;
+ chunk->nextPage++;
+
+ /* update balloon size */
+ b->nPages++;
+
+ /* everything OK */
+ return(BALLOON_SUCCESS);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_FreePage --
+ *
+ * Attempts to deallocate a physical page, deflating balloon "b".
+ * Informs monitor of PPN for deallocated page via backdoor if
+ * "monitorUnlock" is specified.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_FreePage(Balloon *b, int monitorUnlock)
+{
+ BalloonChunk *chunk;
+ unsigned long page;
+ int status;
+
+ chunk = b->chunks;
+
+ while ((chunk != NULL) && (chunk->nextPage == 0)) {
+ /* destroy empty chunk */
+ BalloonChunk_Remove(&b->chunks, chunk);
+ BalloonChunk_Destroy(chunk);
+
+ /* update stats */
+ b->nChunks--;
+
+ chunk = b->chunks;
+ }
+
+ if (chunk == NULL) {
+ return(BALLOON_FAILURE);
+ }
+
+ /* select page to deallocate */
+ chunk->nextPage--;
+ page = chunk->page[chunk->nextPage];
+
+ /* inform monitor via backdoor */
+ if (monitorUnlock) {
+ status = Balloon_MonitorUnlockPage(b, page);
+ if (status != BALLOON_SUCCESS) {
+ /* reset next pointer, fail */
+ chunk->nextPage++;
+ return(status);
+ }
+ }
+
+ /* deallocate page */
+ BalloonPrimFreePage(page);
+ STATS_INC(b->stats.primFree);
+
+ /* update balloon size */
+ b->nPages--;
+
+ /* reclaim chunk, if empty */
+ if (chunk->nextPage == 0) {
+ /* destroy empty chunk */
+ BalloonChunk_Remove(&b->chunks, chunk);
+ BalloonChunk_Destroy(chunk);
+
+ /* update stats */
+ b->nChunks--;
+ }
+
+ /* everything OK */
+ return(BALLOON_SUCCESS);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonDecreaseRateAlloc --
+ *
+ * Wrapper to quickly reduce the page allocation rate. This function
+ * is called only when a CANSLEEP allocation fails. This implies severe
+ * memory pressure inside the guest, so quickly decrease the rateAlloc.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+BalloonDecreaseRateAlloc(Balloon *b)
+{
+ if (BALLOON_RATE_ADAPT) {
+ b->rateAlloc = MAX(b->rateAlloc / 2, BALLOON_RATE_ALLOC_MIN);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonIncreaseRateAlloc --
+ *
+ * Wrapper to increase the page allocation rate.
+ *
+ * This function is called when the balloon target is met or
+ * b->rateAlloc (or more) pages have been successfully allocated.
+ * This implies that the guest may not be under high memory
+ * pressure. So let us increase the rateAlloc.
+ *
+ * If meeting balloon target requires less than b->rateAlloc
+ * pages, then we do not change the page allocation rate.
+ *
+ * If the number of pages successfully allocated (nAlloc) is far
+ * higher than b->rateAlloc, then it implies that NOSLEEP
+ * allocations are highly successful. Therefore, we predict that
+ * the guest is under no memory pressure, and so increase
+ * b->rateAlloc quickly.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+BalloonIncreaseRateAlloc(Balloon *b, uint32 nAlloc)
+{
+ if (BALLOON_RATE_ADAPT) {
+ if (nAlloc >= b->rateAlloc) {
+ uint32 mult = nAlloc / b->rateAlloc;
+ b->rateAlloc = MIN(b->rateAlloc + mult * BALLOON_RATE_ALLOC_INC,
+ BALLOON_RATE_ALLOC_MAX);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonInflate--
+ *
+ * Attempts to allocate physical pages to inflate balloon.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+BalloonInflate(Balloon *b, uint32 target)
+{
+ int status, allocations = 0;
+ uint32 i, nAllocNoSleep, nAllocCanSleep;
+
+ /*
+ * First try NOSLEEP page allocations to inflate balloon.
+ *
+ * If we do not throttle nosleep allocations, we can drain all
+ * free pages in the guest quickly (if the balloon target is high).
+ * As a side-effect, draining free pages helps to inform (force)
+ * the guest to start swapping if balloon target is not met yet,
+ * which is a desired behavior. However, balloon driver can consume
+ * all available CPU cycles if too many pages are allocated in a
+ * second. Therefore, we throttle nosleep allocations even when
+ * the guest is not under memory pressure. OTOH, if we have already
+ * predicted that the guest is under memory pressure, then we
+ * slowdown page allocations considerably.
+ */
+ if (b->slowPageAllocationCycles > 0) {
+ nAllocNoSleep = MIN(target - b->nPages, b->rateAlloc);
+ } else {
+ nAllocNoSleep = MIN(target - b->nPages, BALLOON_NOSLEEP_ALLOC_MAX);
+ }
+
+ for (i = 0; i < nAllocNoSleep; i++) {
+ /* Try NOSLEEP allocation */
+ status = Balloon_AllocPage(b, BALLOON_PAGE_ALLOC_NOSLEEP);
+ if (status != BALLOON_SUCCESS) {
+ if (status != BALLOON_PAGE_ALLOC_FAILURE) {
+ /*
+ * Not a page allocation failure, so release non-balloonable
+ * pages, and fail.
+ */
+ Balloon_ErrorPagesFree(b);
+ return(status);
+ }
+ /*
+ * NOSLEEP page allocation failed, so the guest is under memory
+ * pressure. Let us slowdown page allocations for next few
+ * cycles so that the guest gets out of memory pressure.
+ */
+ b->slowPageAllocationCycles = SLOW_PAGE_ALLOCATION_CYCLES;
+ break;
+ }
+
+ if (++allocations > BALLOON_ALLOC_YIELD_THRESHOLD) {
+ os_yield();
+ allocations = 0;
+ }
+ }
+
+ /*
+ * Check whether nosleep allocation successfully zapped nAllocNoSleep
+ * pages.
+ */
+ if (i == nAllocNoSleep) {
+ BalloonIncreaseRateAlloc(b, nAllocNoSleep);
+ /* release non-balloonable pages, succeed */
+ Balloon_ErrorPagesFree(b);
+ return(BALLOON_SUCCESS);
+ } else {
+ /*
+ * NOSLEEP allocation failed, so the guest is under memory pressure.
+ * If already b->rateAlloc pages were zapped, then succeed. Otherwise,
+ * try CANSLEEP allocation.
+ */
+ if (i > b->rateAlloc) {
+ BalloonIncreaseRateAlloc(b, i);
+ /* release non-balloonable pages, succeed */
+ Balloon_ErrorPagesFree(b);
+ return(BALLOON_SUCCESS);
+ } else {
+ /* update successful NOSLEEP allocations, and proceed */
+ nAllocNoSleep = i;
+ }
+ }
+
+ /*
+ * Use CANSLEEP page allocation to inflate balloon if below target.
+ *
+ * Sleep allocations are required only when nosleep allocation fails.
+ * This implies that the guest is already under memory pressure, so
+ * let us always throttle canSleep allocations. The total number pages
+ * allocated using noSleep and canSleep methods is throttled at
+ * b->rateAlloc per second when the guest is under memory pressure.
+ */
+ nAllocCanSleep = target - b->nPages;
+ nAllocCanSleep = MIN(nAllocCanSleep, b->rateAlloc - nAllocNoSleep);
+
+ for (i = 0; i < nAllocCanSleep; i++) {
+ /* Try CANSLEEP allocation */
+ status = Balloon_AllocPage(b, BALLOON_PAGE_ALLOC_CANSLEEP);
+ if(status != BALLOON_SUCCESS) {
+ if (status == BALLOON_PAGE_ALLOC_FAILURE) {
+ /*
+ * CANSLEEP page allocation failed, so guest is under severe
+ * memory pressure. Quickly decrease rateAlloc.
+ */
+ BalloonDecreaseRateAlloc(b);
+ }
+ /* release non-balloonable pages, fail */
+ Balloon_ErrorPagesFree(b);
+ return(status);
+ }
+
+ if (++allocations > BALLOON_ALLOC_YIELD_THRESHOLD) {
+ os_yield();
+ allocations = 0;
+ }
+ }
+
+ /*
+ * Either met the balloon target or b->rateAlloc pages have been
+ * successfully zapped.
+ */
+ BalloonIncreaseRateAlloc(b, nAllocNoSleep + nAllocCanSleep);
+
+ /* release non-balloonable pages, succeed */
+ Balloon_ErrorPagesFree(b);
+ return(BALLOON_SUCCESS);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonDeflate --
+ *
+ * Frees physical pages to deflate balloon.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+BalloonDeflate(Balloon *b, uint32 target)
+{
+ int status, i;
+ uint32 nFree = b->nPages - target;
+
+ /* limit deallocation rate */
+ nFree = MIN(nFree, b->rateFree);
+
+ /* free pages to reach target */
+ for (i = 0; i < nFree; i++) {
+ if ((status = Balloon_FreePage(b, TRUE)) != BALLOON_SUCCESS) {
+ if (BALLOON_RATE_ADAPT) {
+ /* quickly decrease rate if error */
+ b->rateFree = MAX(b->rateFree / 2, BALLOON_RATE_FREE_MIN);
+ }
+ return(status);
+ }
+ }
+
+ if (BALLOON_RATE_ADAPT) {
+ /* slowly increase rate if no errors */
+ b->rateFree = MIN(b->rateFree + BALLOON_RATE_FREE_INC,
+ BALLOON_RATE_FREE_MAX);
+ }
+
+ /* everything OK */
+ return(BALLOON_SUCCESS);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_AdjustSize --
+ *
+ * Attempts to allocate or deallocate physical pages in order
+ * to reach desired "target" size for balloon "b".
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_AdjustSize(Balloon *b, uint32 target)
+{
+ /* done if already at target */
+ if (b->nPages == target) {
+ return(BALLOON_SUCCESS);
+ }
+
+ /* inflate balloon if below target */
+ if (b->nPages < target) {
+ return BalloonInflate(b, target);
+ }
+
+ /* deflate balloon if above target */
+ if (b->nPages > target) {
+ return BalloonDeflate(b, target);
+ }
+
+ /* not reached */
+ return(BALLOON_FAILURE);
+}
+
+/*
+ * Backdoor Operations
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_MonitorStart --
+ *
+ * Attempts to contact monitor via backdoor to begin operation.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_MonitorStart(Balloon *b)
+{
+ uint32 status, target;
+ Backdoor_proto bp;
+
+ /* prepare backdoor args */
+ bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_START;
+ bp.in.size = BALLOON_PROTOCOL_VERSION;
+
+ /* invoke backdoor */
+ Backdoor_Balloon(&bp);
+
+ /* parse return values */
+ status = bp.out.ax.word;
+ target = bp.out.bx.word;
+
+ /* update stats */
+ STATS_INC(b->stats.start);
+ if (status != BALLOON_SUCCESS) {
+ STATS_INC(b->stats.startFail);
+ }
+
+ /* everything OK */
+ return(status);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_MonitorGuestType --
+ *
+ * Attempts to contact monitor and report guest OS identity.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_MonitorGuestType(Balloon *b)
+{
+ uint32 status, target;
+ Backdoor_proto bp;
+
+ /* prepare backdoor args */
+ bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_GUEST_ID;
+ bp.in.size = BalloonGuestType();
+
+ /* invoke backdoor */
+ Backdoor_Balloon(&bp);
+
+ /* parse return values */
+ status = bp.out.ax.word;
+ target = bp.out.bx.word;
+
+ /* set flag if reset requested */
+ if (status == BALLOON_ERROR_RESET) {
+ b->resetFlag = 1;
+ }
+
+ /* update stats */
+ STATS_INC(b->stats.guestType);
+ if (status != BALLOON_SUCCESS) {
+ STATS_INC(b->stats.guestTypeFail);
+ }
+
+ /* everything OK */
+ return(status);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_MonitorGetTarget --
+ *
+ * Attempts to contact monitor via backdoor to obtain desired
+ * balloon size.
+ *
+ * Predicts the maximum achievable balloon size and sends it
+ * to vmm => vmkernel via vEbx register.
+ *
+ * os_predict_max_balloon_pages() returns either predicted max balloon
+ * pages or BALLOON_MAX_SIZE_USE_CONFIG. In the later scenario,
+ * vmkernel uses global config options for determining a guest's max
+ * balloon size. Note that older vmballoon drivers set vEbx to
+ * BALLOON_MAX_SIZE_USE_CONFIG, i.e., value 0 (zero). So vmkernel
+ * will fallback to config-based max balloon size estimation.
+ *
+ * Results:
+ * If successful, sets "target" to value obtained from monitor,
+ * and returns BALLOON_SUCCESS. Otherwise returns error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_MonitorGetTarget(Balloon *b, uint32 *target)
+{
+ Backdoor_proto bp;
+ uint32 status;
+
+ /* prepare backdoor args */
+ bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_TARGET;
+ bp.in.size = os_predict_max_balloon_pages();
+
+ /* invoke backdoor */
+ Backdoor_Balloon(&bp);
+
+ /* parse return values */
+ status = bp.out.ax.word;
+ *target = bp.out.bx.word;
+
+ /* set flag if reset requested */
+ if (status == BALLOON_ERROR_RESET) {
+ b->resetFlag = 1;
+ }
+
+ /* update stats */
+ STATS_INC(b->stats.target);
+ if (status != BALLOON_SUCCESS) {
+ STATS_INC(b->stats.targetFail);
+ }
+
+ /* everything OK */
+ return(status);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_MonitorLockPage --
+ *
+ * Attempts to contact monitor and add PPN containing "addr"
+ * to set of "balloon locked" pages.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_MonitorLockPage(Balloon *b, unsigned long addr)
+{
+ unsigned long ppn;
+ uint32 ppn32;
+ uint32 status, target;
+ Backdoor_proto bp;
+
+ /* convert kernel-mapped "physical addr" to ppn */
+ ppn = AddrToPPN(addr);
+
+ /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
+ ppn32 = (uint32)ppn;
+ if (ppn32 != ppn) {
+ return BALLOON_ERROR_PPN_INVALID;
+ }
+
+ /* prepare backdoor args */
+ bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_LOCK;
+ bp.in.size = ppn32;
+
+ /* invoke backdoor */
+ Backdoor_Balloon(&bp);
+
+ /* parse return values */
+ status = bp.out.ax.word;
+ target = bp.out.bx.word;
+
+ /* set flag if reset requested */
+ if (status == BALLOON_ERROR_RESET) {
+ b->resetFlag = 1;
+ }
+
+ /* update stats */
+ STATS_INC(b->stats.lock);
+ if (status != BALLOON_SUCCESS) {
+ STATS_INC(b->stats.lockFail);
+ }
+
+ /* everything OK */
+ return(status);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Balloon_MonitorUnlockPage --
+ *
+ * Attempts to contact monitor and remove PPN containing "addr"
+ * from set of "balloon locked" pages.
+ *
+ * Results:
+ * Returns BALLOON_SUCCESS if successful, otherwise error code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+Balloon_MonitorUnlockPage(Balloon *b, unsigned long addr)
+{
+ unsigned long ppn;
+ uint32 ppn32;
+ uint32 status, target;
+ Backdoor_proto bp;
+
+ /* convert kernel-mapped "physical addr" to ppn */
+ ppn = AddrToPPN(addr);
+
+ /* Ensure PPN fits in 32-bits, i.e. guest memory is limited to 16TB. */
+ ppn32 = (uint32)ppn;
+ if (ppn32 != ppn) {
+ return BALLOON_ERROR_PPN_INVALID;
+ }
+
+ /* prepare backdoor args */
+ bp.in.cx.halfs.low = BALLOON_BDOOR_CMD_UNLOCK;
+ bp.in.size = ppn32;
+
+ /* invoke backdoor */
+ Backdoor_Balloon(&bp);
+
+ /* parse return values */
+ status = bp.out.ax.word;
+ target = bp.out.bx.word;
+
+ /* set flag if reset requested */
+ if (status == BALLOON_ERROR_RESET) {
+ b->resetFlag = 1;
+ }
+
+ /* update stats */
+ STATS_INC(b->stats.unlock);
+ if (status != BALLOON_SUCCESS) {
+ STATS_INC(b->stats.unlockFail);
+ }
+
+ /* everything OK */
+ return(status);
+}
+
+/*
+ * Module Operations
+ */
+
+static int
+BalloonModuleInit(void)
+{
+ static int initialized = 0;
+ Balloon *b = &globalBalloon;
+
+ /* initialize only once */
+ if (initialized++) {
+ return(BALLOON_FAILURE);
+ }
+
+ /* initialize global state */
+ Balloon_Init(b);
+
+ /* os-specific initialization */
+ os_init(BALLOON_NAME, BALLOON_NAME_VERBOSE, BalloonProcRead);
+ os_timer_init(Balloon_BH, (void *) b, os_timer_hz());
+
+ /* start timer */
+ Balloon_StartTimer(b);
+
+ /* everything OK */
+ return(BALLOON_SUCCESS);
+}
+
+static void
+BalloonModuleCleanup(void)
+{
+ Balloon *b = &globalBalloon;
+
+ /* stop timer */
+ Balloon_StopTimer(b);
+
+ /*
+ * Deallocate all reserved memory, and reset connection with monitor.
+ * Reset connection before deallocating memory to avoid potential for
+ * additional spurious resets from guest touching deallocated pages.
+ */
+ (void) Balloon_MonitorStart(b);
+ Balloon_Deallocate(b);
+
+ /* os-specific cleanup */
+ os_cleanup();
+}
+
+int init_module(void)
+{
+ return(BalloonModuleInit());
+}
+
+void cleanup_module(void)
+{
+ BalloonModuleCleanup();
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2000 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * vmballoon.h: Definitions and macros for vmballoon driver.
+ */
+
+#ifndef VMBALLOON_H
+#define VMBALLOON_H
+
+#include "vm_basic_types.h"
+
+/*
+ * Page allocation flags
+ */
+typedef enum BalloonPageAllocType {
+ BALLOON_PAGE_ALLOC_NOSLEEP = 0,
+ BALLOON_PAGE_ALLOC_CANSLEEP = 1,
+ BALLOON_PAGE_ALLOC_TYPES_NR, // total number of alloc types
+} BalloonPageAllocType;
+
+/*
+ * Types
+ */
+
+typedef struct {
+ /* current status */
+ uint32 nPages;
+ uint32 nPagesTarget;
+
+ /* adjustment rates */
+ uint32 rateAlloc;
+ uint32 rateFree;
+
+ /* high-level operations */
+ uint32 timer;
+
+ /* primitives */
+ uint32 primAlloc[BALLOON_PAGE_ALLOC_TYPES_NR];
+ uint32 primAllocFail[BALLOON_PAGE_ALLOC_TYPES_NR];
+ uint32 primFree;
+ uint32 primErrorPageAlloc;
+ uint32 primErrorPageFree;
+
+ /* monitor operations */
+ uint32 lock;
+ uint32 lockFail;
+ uint32 unlock;
+ uint32 unlockFail;
+ uint32 target;
+ uint32 targetFail;
+ uint32 start;
+ uint32 startFail;
+ uint32 guestType;
+ uint32 guestTypeFail;
+} BalloonStats;
+
+/*
+ * Operations
+ */
+
+extern void BalloonGetStats(BalloonStats *stats);
+extern int init_module(void);
+extern void cleanup_module(void);
+
+#endif /* VMBALLOON_H */
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * vmballoon_kstats.c --
+ *
+ * Functions reporting status for vmballoon driver in the form of
+ * kstats.
+ */
+
+/*
+ * Compile-Time Options
+ */
+
+#define BALLOON_STATS
+#define BALLOON_STATS_PROCFS
+
+#include <sys/types.h>
+#include <sys/kstat.h>
+#include <sys/errno.h>
+#include "os.h"
+#include "vmballoon.h"
+#include "vmballoon_kstats.h"
+
+/*
+ * Information to be reported to user level through kstats. This
+ * table should be kept in sync with the corresponding info reported
+ * through procfs by the linux driver. To display this information
+ * on a Solaris system with the driver loaded, run "kstat -m vmmemctl".
+ */
+typedef struct {
+ kstat_named_t nPagesTarget;
+ kstat_named_t nPages;
+ kstat_named_t rateAlloc;
+ kstat_named_t rateFree;
+ kstat_named_t timer;
+ kstat_named_t start;
+ kstat_named_t startFail;
+ kstat_named_t guestType;
+ kstat_named_t guestTypeFail;
+ kstat_named_t lock;
+ kstat_named_t lockFail;
+ kstat_named_t unlock;
+ kstat_named_t unlockFail;
+ kstat_named_t target;
+ kstat_named_t targetFail;
+ kstat_named_t primAlloc[BALLOON_PAGE_ALLOC_TYPES_NR];
+ kstat_named_t primAllocFail[BALLOON_PAGE_ALLOC_TYPES_NR];
+ kstat_named_t primFree;
+ kstat_named_t primErrorPageAlloc;
+ kstat_named_t primErrorPageFree;
+} BalloonKstats;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BalloonKstatUpdate --
+ *
+ * Ballon driver status reporting routine.
+ *
+ * Results:
+ * Copies current driver status and statistics into kstat structure
+ * for reporting to user level.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+BalloonKstatUpdate(kstat_t *ksp, int rw)
+{
+ int i;
+ BalloonStats stats;
+ BalloonKstats *bkp = ksp->ks_data;
+
+ if (rw == KSTAT_WRITE)
+ return (EACCES);
+
+ BalloonGetStats(&stats);
+
+ /* size info */
+ bkp->nPagesTarget.value.ui32 = stats.nPagesTarget;
+ bkp->nPages.value.ui32 = stats.nPages;
+
+ /* rate info */
+ bkp->rateAlloc.value.ui32 = stats.rateAlloc;
+ bkp->rateFree.value.ui32 = stats.rateFree;
+
+ /* statistics */
+ bkp->timer.value.ui32 = stats.timer;
+ bkp->start.value.ui32 = stats.start;
+ bkp->startFail.value.ui32 = stats.startFail;
+ bkp->guestType.value.ui32 = stats.guestType;
+ bkp->guestTypeFail.value.ui32 = stats.guestTypeFail;
+ bkp->lock.value.ui32 = stats.lock;
+ bkp->lockFail.value.ui32 = stats.lockFail;
+ bkp->unlock.value.ui32 = stats.unlock;
+ bkp->unlockFail.value.ui32 = stats.unlockFail;
+ bkp->target.value.ui32 = stats.target;
+ bkp->targetFail.value.ui32 = stats.targetFail;
+ for (i = 0; i < BALLOON_PAGE_ALLOC_TYPES_NR; i++) {
+ bkp->primAlloc[i].value.ui32 = stats.primAlloc[i];
+ bkp->primAllocFail[i].value.ui32 = stats.primAllocFail[i];
+ }
+ bkp->primFree.value.ui32 = stats.primFree;
+ bkp->primErrorPageAlloc.value.ui32 = stats.primErrorPageAlloc;
+ bkp->primErrorPageFree.value.ui32 = stats.primErrorPageFree;
+
+ return 0;
+}
+
+/*
+ * Set up statistics for the balloon driver. Creates and initializes
+ * the kstats structure.
+ */
+kstat_t *
+BalloonKstatCreate(void)
+{
+ kstat_t *ksp;
+ BalloonKstats *bkp;
+
+ ksp = kstat_create("vmmemctl", 0, "vmmemctl", "vm", KSTAT_TYPE_NAMED,
+ sizeof (BalloonKstats) / sizeof (kstat_named_t), 0);
+
+ if (ksp == NULL)
+ return (NULL); /* can't allocate space, give up (no kstats) */
+
+ bkp = ksp->ks_data;
+ kstat_named_init(&bkp->nPagesTarget, "targetPages", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->nPages, "currentPages", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->rateAlloc, "rateAlloc", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->rateFree, "rateFree", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->timer, "timer", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->start, "start", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->startFail, "startFail", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->guestType, "guestType", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->guestTypeFail, "guestTypeFail", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->lock, "lock", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->lockFail, "lockFail", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->unlock, "unlock", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->unlockFail, "unlockFail", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->target, "target", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->targetFail, "targetFail", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->primAlloc[BALLOON_PAGE_ALLOC_NOSLEEP],
+ "primAllocNoSleep", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->primAlloc[BALLOON_PAGE_ALLOC_CANSLEEP],
+ "primAllocCanSleep", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->primAllocFail[BALLOON_PAGE_ALLOC_NOSLEEP],
+ "primAllocNoSleepFail", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->primAllocFail[BALLOON_PAGE_ALLOC_CANSLEEP],
+ "primAllocCanSleepFail", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->primFree, "primFree", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->primErrorPageAlloc, "errAlloc", KSTAT_DATA_UINT32);
+ kstat_named_init(&bkp->primErrorPageFree, "errFree", KSTAT_DATA_UINT32);
+
+ /* set update function to be run when kstats are read */
+ ksp->ks_update = BalloonKstatUpdate;
+
+ kstat_install(ksp);
+
+ return ksp;
+}
+
+void BalloonKstatDelete(kstat_t *ksp)
+{
+ if (ksp != NULL)
+ kstat_delete(ksp);
+}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * vmballoon_kstats.h --
+ *
+ * External definitions associated with the functions providing
+ * kstats for the vmmemctl driver.
+ */
+
+#ifndef VMBALLOON_KSTATS_H
+#define VMBALLOON_KSTATS_H
+
+extern kstat_t *BalloonKstatCreate(void);
+extern void BalloonKstatDelete(kstat_t *);
+
+#endif /* VMBALLOON_KSTATS_H */
--- /dev/null
+#
+# Copyright 2005-2008 VMware, Inc. All rights reserved.
+#
+
+name="vmmemctl" parent="pseudo" instance=0;
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * vmmemctl.h --
+ *
+ * Definitions for the interface between vmmemctl daemon (vmmemctld)
+ * and driver.
+ */
+
+#ifndef _VMMEMCTL_H
+#define _VMMEMCTL_H
+
+#define VMMIOC (0xba << 8) /* prefix */
+#define VMMIOCWORK (VMMIOC | 0x01)
+
+#endif /* _VMMEMCTL_H */
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2005 VMware, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of the Common
+ * Development and Distribution License (the "License") version 1.0
+ * and no later version. You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at
+ * http://www.opensource.org/licenses/cddl1.php
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ *********************************************************/
+
+/*
+ * vmmemctld.c --
+ *
+ * Simple daemon that provides a worker thread for the vmmemctl
+ * driver. Note that opening the device node causes the driver
+ * to load, and the driver can't be unloaded as long as we're
+ * running inside it.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "vm_basic_types.h"
+#include "vmmemctl.h"
+
+static const char *pname;
+static const char dpath[] = "/devices/pseudo/vmmemctl@0:0";
+
+static void myperror(const char *str)
+{
+ fprintf(stderr, "%s: ", pname);
+ perror(str);
+}
+
+int main(int argc, char **argv)
+{
+ int err;
+ pid_t pid;
+ int fd;
+
+ pname = argv[0];
+
+ /*
+ * Basic sanity checks
+ */
+ if (chdir("/") < 0) {
+ myperror("chdir");
+ return 1;
+ }
+
+ /*
+ * Run in background
+ */
+ pid = fork();
+ if (pid < 0) {
+ myperror("fork");
+ return 1;
+ }
+ if (pid != 0) {
+ /*
+ * Parent writes pidfile if specified.
+ */
+ if (argc >= 3 && strcmp(argv[1], "--background") == 0) {
+ int fd;
+ int len;
+ char buf[64];
+
+ (void) unlink(argv[2]);
+
+ fd = open(argv[2], O_CREAT | O_EXCL | O_WRONLY);
+ if (fd < 0) {
+ myperror("open");
+ return 1;
+ }
+
+ len = snprintf(buf, sizeof buf, "%"FMTPID"\n", pid);
+ if (len >= sizeof buf) {
+ /* String was truncated */
+ myperror("snprintf");
+ close(fd);
+ return 1;
+ }
+
+ if (write(fd, buf, len) != len) {
+ myperror("write");
+ close(fd);
+ return 1;
+ }
+
+ if (close(fd) != 0) {
+ myperror("close");
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ /*
+ * Clean up file descriptors and detach from controlling tty.
+ */
+ closefrom(0);
+ (void) open("/dev/null", O_RDONLY);
+ (void) open("/dev/null", O_WRONLY);
+ (void) dup(1);
+ (void) setsid();
+
+ /*
+ * Call into the driver to do work.
+ */
+ if ((fd = open(dpath, O_RDWR)) == -1) {
+ myperror("open");
+ return 1;
+ }
+
+ /*
+ * If ioctl returns EINTR, we were interrupted by a non-fatal signal.
+ * Call back into the driver to continue working.
+ */
+ while ((err = ioctl(fd, VMMIOCWORK, 0)) == EINTR)
+ ;
+
+ if (err != 0) {
+ myperror("ioctl");
+ return 1;
+ }
+
+ /*
+ * We've been told to exit cleanly.
+ */
+ (void) close(fd);
+ return 0;
+}
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
+#define PCI_DEVICE_ID_VMWARE_VMXWIFI 0x07B8
#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
/* The hypervisor device might grow. Please leave room
/*********************************************************
- * Copyright (C) 1998-2008 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2009 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
#endif
#ifdef __FreeBSD__
-#include <sys/param.h> /* For __FreeBSD_version */
+#include <sys/param.h> /* For __FreeBSD_version */
#endif
#if !defined(USING_AUTOCONF)
# ifdef KLD_MODULE
# include <sys/types.h>
# else
-# if !defined(VMKERNEL) && (__FreeBSD_version >= 500043)
-# include <inttypes.h>
+# if __FreeBSD_version >= 500043
+# if !defined(VMKERNEL)
+# include <inttypes.h>
+# endif
# include <sys/types.h>
# else
# include <sys/inttypes.h>
#define CONST3264U(a) (a)
#endif
+#define MIN_INT8 ((int8)0x80)
+#define MAX_INT8 ((int8)0x7f)
+
+#define MIN_UINT8 ((uint8)0)
+#define MAX_UINT8 ((uint8)0xff)
+
+#define MIN_INT16 ((int16)0x8000)
+#define MAX_INT16 ((int16)0x7fff)
+
+#define MIN_UINT16 ((uint16)0)
+#define MAX_UINT16 ((uint16)0xffff)
+
#define MIN_INT32 ((int32)0x80000000)
#define MAX_INT32 ((int32)0x7fffffff)
***********************************************************************
* STRUCT_OFFSET_CHECK -- */ /**
*
- * \brief Check if the actual offsef of a member in a structure
+ * \brief Check if the actual offsef of a member in a structure
* is what is expected
- *
+ *
*
* \param[in] STRUCT Structure the member is a part of.
* \param[in] MEMBER Member to check the offset of.
* STRUCT_SIZE_CHECK -- */ /**
*
* \brief Check if the actual size of a structure is what is expected
- *
+ *
*
* \param[in] STRUCT Structure whose size is to be checked.
* \param[in] SIZE Expected size of STRUCT.
#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
+#define PCI_DEVICE_ID_VMWARE_VMXWIFI 0x07B8
#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
/* The hypervisor device might grow. Please leave room
#define VMXNET3_REG_ICR 0x38 /* Interrupt Cause Register */
#define VMXNET3_REG_ECR 0x40 /* Event Cause Register */
+#define VMXNET3_REG_WSAL 0xF00 /* Wireless Shared Address Lo */
+#define VMXNET3_REG_WSAH 0xF08 /* Wireless Shared Address Hi */
+#define VMXNET3_REG_WCMD 0xF18 /* Wireless Command */
+
/* BAR 0 */
#define VMXNET3_REG_IMR 0x0 /* Interrupt Mask Register */
#define VMXNET3_REG_TXPROD 0x600 /* Tx Producer Index */
#define VMXNET3_LINK_UP (10000 << 16 | 1) // 10 Gbps, up
#define VMXNET3_LINK_DOWN 0
+
+#define VMXWIFI_DRIVER_SHARED_LEN 8192
+
#endif /* _VMXNET3_DEFS_H_ */
echo `date` ": Executing '$0'"
echo
+# Start the network.
+/etc/netstart
+
scriptsdir="`dirname $0`/scripts/`basename $0`.d"
if [ -d "$scriptsdir" ]; then
for scriptfile in "$scriptsdir"/*; do
done
fi
-# Start the network.
-/etc/netstart
# main
#
-scriptsdir="`dirname $0`/scripts/`basename $0`.d"
-if [ -d "$scriptsdir" ]; then
- for scriptfile in "$scriptsdir"/*; do
- [ -x "$scriptfile" ] && "$scriptfile" resume-vm
- done
-fi
-
network=`find_networking_script`
if [ "$network" != "error" ]; then
"$network" restart
rescue_NIC
fi
+scriptsdir="`dirname $0`/scripts/`basename $0`.d"
+if [ -d "$scriptsdir" ]; then
+ for scriptfile in "$scriptsdir"/*; do
+ [ -x "$scriptfile" ] && "$scriptfile" resume-vm
+ done
+fi
+
exit "$status"
echo `date` ": Executing '$0'"
echo
-scriptsdir="`dirname $0`/scripts/`basename $0`.d"
-if [ -d "$scriptsdir" ]; then
- for scriptfile in "$scriptsdir"/*; do
- [ -x "$scriptfile" ] && "$scriptfile" resume-vm
- done
-fi
-
ACTIVELIST=/var/run/vmware-active-nics
if [ -f $ACTIVELIST ] ; then
done
rm $ACTIVELIST
fi
+
+scriptsdir="`dirname $0`/scripts/`basename $0`.d"
+if [ -d "$scriptsdir" ]; then
+ for scriptfile in "$scriptsdir"/*; do
+ [ -x "$scriptfile" ] && "$scriptfile" resume-vm
+ done
+fi
+
if (strcmp(data->name, stateChangeCmdTable[i].tcloCmd) == 0) {
gchar *script;
const char *result;
+ const char *confName;
Bool ret;
state->stateChgInProgress = stateChangeCmdTable[i].id;
return RPCIN_SETRETVALS(data, "", TRUE);
}
+ confName = stateChgConfNames[stateChangeCmdTable[i].id];
script = g_key_file_get_string(state->ctx->config,
"powerops",
- stateChgConfNames[stateChangeCmdTable[i].id],
+ confName,
NULL);
if (script == NULL) {
char *dfltPath;
const char *dfltScript;
- dfltScript = GuestApp_GetDefaultScript(stateChangeCmdTable[i].name);
+ dfltScript = GuestApp_GetDefaultScript(confName);
if (dfltScript == NULL) {
g_debug("No default script to run for state change %s.\n",
stateChangeCmdTable[i].name);
#include <unistd.h>
#include <glib/gstdio.h>
#include "file.h"
-#include "system.h"
+#include "hostinfo.h"
#include "unicode.h"
#include "util.h"
#include "vmtools.h"
argvCopy = NULL;
if (gState.pidFile != NULL) {
-#if defined(__APPLE__)
/*
- * The Mac OS main loop uses CoreFoundation classes, and that does not
- * work with fork(). So we must exec() after the fork or the daemon
- * will crash.
- *
- * We at least make sure that argv[0] is an absolute path before
- * exec'ing; but all other path arguments should have been given
- * as absolute paths if '--background' was used, or things may not
- * work as expected.
+ * If argv[0] is not an absolute path, make it so; all other path
+ * arguments should have been given as absolute paths if '--background'
+ * was used, or things may not work as expected.
*/
if (!g_path_is_absolute(argv[0])) {
char *cwd = File_Cwd(NULL);
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--background") == 0 ||
strcmp(argv[i], "-b") == 0) {
- int j;
- for (j = i + 2; j < argc; j++) {
- argv[j - 2] = argv[j];
- }
- argv[j - 2] = NULL;
+ memmove(argv + i, argv + i + 2, (argc - i - 2) * sizeof *argv);
+ argv[argc - 2] = NULL;
break;
}
}
- if (System_Daemon(FALSE, FALSE, gState.pidFile)) {
- execv(argv[0], argv);
- _exit(1);
- } else {
+ if (!Hostinfo_Daemonize(argv[0],
+ argv,
+ HOSTINFO_DAEMONIZE_DEFAULT,
+ gState.pidFile)) {
goto exit;
}
-#else
- if (!System_Daemon(FALSE, FALSE, gState.pidFile)) {
- goto exit;
- }
-#endif
+ return 0;
}
if (!ToolsCore_Setup(&gState)) {
module = g_module_open(path, G_MODULE_BIND_LOCAL);
if (module == NULL) {
- g_warning("Opening plugin '%s' failed.\n", entry);
+ g_warning("Opening plugin '%s' failed: %s.\n", entry, g_module_error());
goto next;
}
};
static gboolean gSignalReceived = FALSE;
+static ToolsAppCtx *gCtx;
/**
TestDebugSendNext(RpcDebugMsgMapping *rpcdata)
{
static RpcDebugMsgList msgList = { gRpcMessages, 0 };
- return RpcDebug_SendNext(rpcdata, &msgList);
+ if (!RpcDebug_SendNext(rpcdata, &msgList)) {
+ /*
+ * Test for bug 391553: send two resets in sequence without
+ * pumping the main loop. The channel should handle the second
+ * reset successfully instead of asserting.
+ */
+ int i;
+ for (i = 0; i < 2; i++) {
+ RpcInData data;
+ memset(&data, 0, sizeof data);
+ data.clientData = gCtx->rpc;
+ data.appCtx = gCtx;
+ data.args = "reset";
+ data.argsSize = sizeof "reset";
+
+ g_debug("reset test %d\n", i + 1);
+ RpcChannel_Dispatch(&data);
+ }
+ return FALSE;
+ }
+ return TRUE;
}
g_error("Failed to create test.rpcin.msg1 command.\n");
}
+ gCtx = ctx;
return ®Data;
}
* messages to send.
*
* @param[in] chan Unused.
- *
- * @return TRUE.
*/
-static Bool
+static void
RpcDebugStop(RpcChannel *chan)
{
DbgChannelData *data = chan->_private;
g_source_unref(data->msgTimer);
data->msgTimer = NULL;
}
- return TRUE;
}
* Does nothing.
*
* @param[in] chan The RPC channel instance.
- *
- * @return TRUE.
*/
-static Bool
+static void
RpcDebugShutdown(RpcChannel *chan)
{
DbgChannelData *cdata = chan->_private;
RpcDebug_DecRef(chan->appCtx);
}
g_free(chan->_private);
- return TRUE;
}
DiskHelp(char *progName) // IN: The name of the program obtained from argv[0]
{
printf("disk: perform disk shrink operations\n"
- "Usage: %s shrink <subcommand> [args]\n\n"
+ "Usage: %s disk <subcommand> [args]\n\n"
"Subcommands\n"
" list: list available mountpoints\n"
" shrink <mount-point>: shrinks a file system at the given mountpoint\n",
{
struct DblLnkLst_Links *curr;
- /* XXX The following is only temporary. */
-#ifdef __FreeBSD__
+ /*
+ * On FreeBSD we have a mechanism to assert (but not simply check)
+ * that a lock is held. Since semantic is different (panic that
+ * happens if assertion fails can not be suppressed) we are using
+ * different name.
+ */
+#ifdef os_assert_rwlock_held
os_assert_rwlock_held(&blockedFilesLock);
#else
ASSERT(os_rwlock_held(&blockedFilesLock));
* "device" instead of calling DnD_InitializeBlocking() and bringing along
* a whole host of libs.
*/
- fd = open(VMBLOCK_DEVICE, VMBLOCK_DEVICE_MODE);
+ fd = open(VMBLOCK_FUSE_DEVICE, VMBLOCK_FUSE_DEVICE_MODE);
+ if (fd < 0) {
+ fd = open(VMBLOCK_DEVICE, VMBLOCK_DEVICE_MODE);
+ }
uid = getuid();
gid = getgid();
endif
AM_CFLAGS += @VMWARE_USER_CPPFLAGS@
AM_CFLAGS += -I$(top_builddir)/include
+AM_CFLAGS += -I$(top_srcdir)/lib/dndGuest
AM_CFLAGS += -DRESOLUTION_X11
AM_CFLAGS += -I$(top_srcdir)/services/plugins/vix
vmware_user_LDADD =
vmware_user_LDADD += ../lib/conf/libConf.la
-if HAVE_GTKMM
- vmware_user_LDADD += ../lib/dndGuest/libDndGuest.la
-endif
vmware_user_LDADD += ../lib/eventManager/libEventManager.la
vmware_user_LDADD += ../lib/file/libFile.la
if ENABLE_UNITY
vmware_user_LDADD += ../lib/foundryMsg/libFoundryMsg.la
vmware_user_LDADD += ../lib/backdoor/libBackdoor.la
vmware_user_LDADD += ../lib/dict/libDict.la
+vmware_user_LDADD += ../lib/dndGuest/libDndGuest.la
vmware_user_LDADD += ../lib/dnd/libDnd.la
vmware_user_LDADD += ../lib/dynxdr/libDynxdr.la
vmware_user_LDADD += ../lib/hgfs/libHgfs.la
vmware_user_SOURCES += copyPasteDnDWrapper.cpp
vmware_user_SOURCES += debugStdio.c
vmware_user_SOURCES += dnd.c
+if HAVE_GTKMM
+vmware_user_SOURCES += dndUI.cpp
+vmware_user_SOURCES += dragDetWnd.cpp
+endif
vmware_user_SOURCES += foreignVMToolsDaemon.c
vmware_user_SOURCES += foreignVMToolsNetworking.c
vmware_user_SOURCES += $(top_srcdir)/services/plugins/vix/foundryToolsDaemon.c
gHGFCPFileTransferStatus = FCP_FILE_TRANSFERRING;
}
- if (gBlockFd > 0) {
+ if (DnD_BlockIsReady(&gBlockCtrl)) {
/* Add a block on the staging directory for this command. */
- if (DnD_AddBlock(gBlockFd, gFileRoot)) {
+ if (gBlockCtrl.AddBlock(gBlockCtrl.fd, gFileRoot)) {
Debug("CopyPasteSelectionGetCB: add block [%s].\n", gFileRoot);
blockAdded = TRUE;
} else {
Warning("CopyPasteSelectionGetCB: Unable to add block [%s].\n", gFileRoot);
}
}
-
+
if (!blockAdded) {
/*
* If there is no blocking driver, wait here till file copy is done.
ASSERT(gHGFCPFileTransferStatus == FCP_FILE_TRANSFERRING);
gHGFCPFileTransferStatus = FCP_FILE_TRANSFERRED;
- if (gBlockFd > 0 && !DnD_RemoveBlock(gBlockFd, gFileRoot)) {
+ if (DnD_BlockIsReady(&gBlockCtrl) &&
+ !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
Warning("CopyPasteRpcInHGDataFinishCB: Unable to remove block [%s].\n",
gFileRoot);
}
Bool ret = FALSE;
char *retStr;
int iAtom;
+ Bool usingDnDBlock;
gHGFCPFileTransferStatus = FCP_FILE_TRANSFER_NOT_YET;
/* Parse value string. */
memcpy(data, args + index, listSize);
data[listSize] = '\0';
- if (gBlockFd > 0) {
+ usingDnDBlock = DnD_BlockIsReady(&gBlockCtrl);
+ if (usingDnDBlock) {
/*
* Here we take the last component of the actual file root, which is
* a temporary directory for this DnD operation, and append it to the
retStr = "error construct stagingDirName";
goto exit;
}
- if (sizeof VMBLOCK_MOUNT_POINT - 1 +
+ if (strlen(gBlockCtrl.blockRoot) +
(sizeof DIRSEPS - 1) * 2 + strlen(stagingDirName) >= sizeof mountDirName) {
Debug("CopyPasteHGSetFileList: directory name too large.\n");
retStr = "directory name too large";
goto exit;
}
Str_Sprintf(mountDirName, sizeof mountDirName,
- VMBLOCK_MOUNT_POINT DIRSEPS"%s"DIRSEPS, stagingDirName);
+ "%s" DIRSEPS "%s" DIRSEPS, gBlockCtrl.blockRoot, stagingDirName);
}
/* Add the file root to the relative paths received from host */
- if (!DnD_PrependFileRoot(gBlockFd > 0 ? mountDirName : gFileRoot,
+ if (!DnD_PrependFileRoot(usingDnDBlock ? mountDirName : gFileRoot,
&data, &listSize)) {
Debug("CopyPasteHGSetFileList: error prepending guest file root\n");
retStr = "error prepending file root";
{
if (gHGFCPFileTransferStatus == FCP_FILE_TRANSFERRING) {
File_DeleteDirectoryTree(gFileRoot);
- if (gBlockFd > 0 && !DnD_RemoveBlock(gBlockFd, gFileRoot)) {
+ if (DnD_BlockIsReady(&gBlockCtrl) &&
+ !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
Warning("CopyPasteRpcInHGDataFinishCB: Unable to remove block [%s].\n",
gFileRoot);
}
/**
* @file copyPasteDnDWrapper.cpp
- *
+ *
* This singleton class implements a wrapper around various versions of
- * copy and paste protocols, and provides some convenience functions that
- * help to make VMwareUser a bit cleaner.
+ * copy and paste and dnd protocols, and provides some convenience functions
+ * that help to make VMwareUser a bit cleaner.
*/
#include "copyPasteDnDWrapper.h"
+
extern "C" {
#include "vmwareuserInt.h"
#include "debug.h"
+#include "dndGuest.h"
+#include "unity.h"
}
+class DragDetWnd;
/**
* CopyPasteDnDWrapper is a singleton, here is a pointer to its only instance.
return m_instance;
}
+#if defined(HAVE_GTKMM)
+extern "C" {
+
+/**
+ *
+ * Enter or leave unity mode.
+ *
+ * @param[in] mode enter unity mode if TRUE, else leave.
+ */
+
+void
+CopyPasteDnDWrapper_SetUnityMode(Bool mode)
+{
+ CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance();
+
+ if (wrapper) {
+ wrapper->SetUnityMode(mode);
+ }
+}
+
+}
+#endif
/**
*
CopyPasteDnDWrapper::CopyPasteDnDWrapper() :
#if defined(HAVE_GTKMM)
m_copyPasteUI(NULL),
+ m_dndUI(NULL),
#endif
- m_isRegistered(FALSE),
+ m_isCPRegistered(FALSE),
+ m_isDnDRegistered(FALSE),
m_userData(NULL),
- m_version(-1)
+ m_cpVersion(-1),
+ m_dndVersion(-1),
+ m_isLegacy(false),
+ m_hgWnd(NULL),
+ m_ghWnd(NULL),
+ m_eventQueue(NULL)
{
}
CopyPasteDnDWrapper::~CopyPasteDnDWrapper()
{
- if (IsRegistered()) {
- Unregister();
+ if (IsCPRegistered()) {
+ UnregisterCP();
+ }
+ if (IsDnDRegistered()) {
+ UnregisterDnD();
}
}
*/
void
-CopyPasteDnDWrapper::SetBlockFd(int blockFd)
+CopyPasteDnDWrapper::SetBlockControl(DnDBlockControl *blockCtrl)
{
- Debug("%s: enter %d\n", __FUNCTION__, blockFd);
- mBlockFd = blockFd;
+ Debug("%s: enter %p (%d)\n", __func__, blockCtrl, blockCtrl->fd);
+ m_blockCtrl = blockCtrl;
}
*/
bool
-CopyPasteDnDWrapper::Register()
+CopyPasteDnDWrapper::RegisterCP()
{
- Debug("%s: mBlockFd %d\n", __FUNCTION__, mBlockFd);
- if (IsRegistered()) {
+ Debug("%s: m_blockCtrl %p\n", __func__, m_blockCtrl);
+ if (IsCPRegistered()) {
return TRUE;
}
*/
#if defined(HAVE_GTKMM)
- Debug("%s: enter\n", __FUNCTION__);
- m_copyPasteUI = new CopyPasteUI();
- if (m_copyPasteUI) {
- Debug("%s: Setting block fd to %d\n", __FUNCTION__, mBlockFd);
- m_copyPasteUI->SetBlockFd(mBlockFd);
- m_copyPasteUI->Init();
- SetIsRegistered(TRUE);
- int version = GetVersion();
- Debug("%s: version is %d\n", __FUNCTION__, version);
- if (version >= 3) {
- m_copyPasteUI->VmxCopyPasteVersionChanged(gRpcIn, version);
- m_copyPasteUI->SetCopyPasteAllowed(TRUE);
- } else {
- Debug("%s: version < 3, unregistering.\n", __FUNCTION__);
- Unregister();
+ if (!IsCPRegistered()) {
+ m_copyPasteUI = new CopyPasteUI();
+ if (m_copyPasteUI) {
+ Debug("%s: Setting block control to %p (fd %d)\n",
+ __func__, m_blockCtrl, m_blockCtrl->fd);
+ m_copyPasteUI->SetBlockControl(m_blockCtrl);
+ m_copyPasteUI->Init();
+ SetCPIsRegistered(TRUE);
+ int version = GetCPVersion();
+ Debug("%s: version is %d\n", __FUNCTION__, version);
+ if (version >= 3) {
+ m_copyPasteUI->VmxCopyPasteVersionChanged(gRpcIn, version);
+ m_copyPasteUI->SetCopyPasteAllowed(TRUE);
+ m_isLegacy = false;
+ } else {
+ Debug("%s: version < 3, unregistering.\n", __FUNCTION__);
+ UnregisterCP();
+ }
}
}
+
#endif
- if (!IsRegistered()) {
- Debug("%s: Registering legacy m_userData %lx\n", __FUNCTION__, (long unsigned int) m_userData);
- SetIsRegistered(CopyPaste_Register((GtkWidget *)m_userData));
- if (IsRegistered()) {
- Debug("%s: Registering capability\n", __FUNCTION__);
+ if (!IsCPRegistered()) {
+ Debug("%s: Registering legacy m_userData %lx\n",
+ __func__, (long unsigned int) m_userData);
+ SetCPIsRegistered(CopyPaste_Register((GtkWidget *)m_userData));
+ if (IsCPRegistered()) {
+ Debug("%s: Registering capability\n", __FUNCTION__);
if (!CopyPaste_RegisterCapability()) {
- Unregister();
+ UnregisterCP();
+ }
+ else {
+ m_isLegacy = true;
}
}
}
- return IsRegistered();
+
+ return IsCPRegistered();
}
+
+/**
+ *
+ * Register DnD capabilities with the VMX. Try newest version
+ * first, then fall back to the legacy implementation.
+ *
+ * @return TRUE on success, FALSE on failure
+ */
+
+bool
+CopyPasteDnDWrapper::RegisterDnD()
+{
+ /*
+ * Try to get version 3, and if that fails, go for the compatibility
+ * versions (1 and 2).
+ */
+
+#if defined(HAVE_GTKMM)
+ if (!IsDnDRegistered()) {
+ m_dndUI = new DnDUI(m_eventQueue);
+ if (m_dndUI) {
+ Debug("%s: Setting block control to %p (fd %d)\n",
+ __func__, m_blockCtrl, m_blockCtrl->fd);
+ m_dndUI->SetBlockControl(m_blockCtrl);
+
+ m_dndUI->Init();
+
+ UnityDnD state;
+ state.detWnd = m_dndUI->GetDetWndAsWidget(true);
+ state.setMode = CopyPasteDnDWrapper_SetUnityMode;
+ Unity_SetActiveDnDDetWnd(&state);
+
+ SetDnDIsRegistered(TRUE);
+ int version = GetDnDVersion();
+ Debug("%s: dnd version is %d\n", __FUNCTION__, version);
+ if (version >= 3) {
+ Debug("%s: calling VmxDnDVersionChanged (version %d) and SetDnDAllowed\n",
+ __FUNCTION__, version);
+ m_dndUI->VmxDnDVersionChanged(gRpcIn, version);
+ m_dndUI->SetDnDAllowed(TRUE);
+ m_isLegacy = false;
+ } else {
+ Debug("%s: version < 3, unregistering.\n", __FUNCTION__);
+ UnregisterDnD();
+ }
+ }
+ }
+
+#endif
+ if (!IsDnDRegistered()) {
+ Debug("%s: legacy registering dnd capability\n", __FUNCTION__);
+ if (m_isLegacy) {
+ SetDnDIsRegistered(DnD_Register(m_hgWnd, m_ghWnd));
+ if (IsDnDRegistered()) {
+ Debug("%s: setting up detwnd for Unity\n", __FUNCTION__);
+ UnityDnD state;
+ state.detWnd = m_ghWnd;
+ state.setMode = DnD_SetMode;
+ Unity_SetActiveDnDDetWnd(&state);
+ }
+ }
+ } else if (m_isLegacy && DnD_GetVmxDnDVersion() > 1) {
+ Debug("%s: legacy registering dnd capability\n", __FUNCTION__);
+ if (!DnD_RegisterCapability()) {
+ Debug("%s: legacy unable to register dnd capability\n", __FUNCTION__);
+ UnregisterDnD();
+ }
+ }
+ Debug("%s: dnd is registered? %d\n", __FUNCTION__, (int) IsDnDRegistered());
+ return IsDnDRegistered();
+}
+
+
/**
*
* Unregister copy paste capabilities and do general cleanup.
*/
void
-CopyPasteDnDWrapper::Unregister()
+CopyPasteDnDWrapper::UnregisterCP()
{
- if (!IsRegistered()) {
- return;
- }
+ Debug("%s: enter\n", __FUNCTION__);
+ if (IsCPRegistered()) {
#if defined(HAVE_GTKMM)
- if (m_copyPasteUI) {
- delete m_copyPasteUI;
- m_copyPasteUI = NULL;
- } else {
+ if (m_copyPasteUI) {
+ delete m_copyPasteUI;
+ m_copyPasteUI = NULL;
+ } else {
#endif
- CopyPaste_Unregister((GtkWidget *)m_userData);
+ CopyPaste_Unregister((GtkWidget *)m_userData);
#if defined(HAVE_GTKMM)
+ }
+#endif
+ SetCPIsRegistered(FALSE);
+ m_cpVersion = -1;
}
+}
+
+
+/**
+ *
+ * Unregister DnD capabilities and do general cleanup.
+ */
+
+void
+CopyPasteDnDWrapper::UnregisterDnD()
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ if (IsDnDRegistered()) {
+ if (m_isLegacy) {
+ DnD_Unregister(m_hgWnd, m_ghWnd);
+#if defined(HAVE_GTKMM)
+ } else if (m_dndUI) {
+ delete m_dndUI;
+ m_dndUI = NULL;
#endif
- SetIsRegistered(FALSE);
- m_version = -1;
+ }
+ m_dndVersion = -1;
+ SetDnDIsRegistered(false);
+ return;
+ }
}
*
* Get the version of the copy paste protocol being wrapped.
*
- * @return copy paste protocol version.
+ * @return copy paste protocol version.
+ */
+
+int
+CopyPasteDnDWrapper::GetCPVersion()
+{
+ if (IsCPRegistered()) {
+ m_cpVersion = CopyPaste_GetVmxCopyPasteVersion();
+ }
+ Debug("%s: got version %d\n", __FUNCTION__, m_cpVersion);
+ return m_cpVersion;
+}
+
+
+/**
+ *
+ * Get the version of the DnD protocol being wrapped.
+ *
+ * @return DnD protocol version.
*/
int
-CopyPasteDnDWrapper::GetVersion()
+CopyPasteDnDWrapper::GetDnDVersion()
{
- if (IsRegistered()) {
- m_version = CopyPaste_GetVmxCopyPasteVersion();
+ if (IsDnDRegistered()) {
+ m_dndVersion = DnD_GetVmxDnDVersion();
}
- Debug("%s: got version %d\n", __FUNCTION__, m_version);
- return m_version;
+ Debug("%s: got version %d\n", __FUNCTION__, m_dndVersion);
+ return m_dndVersion;
}
+
/**
*
* Set a flag indicating that we are wrapping an initialized and registered
* copy paste implementation, or not.
*
- * @param[in] isRegistered If TRUE, protocol is registered, otherwise FALSE.
+ * @param[in] isRegistered If TRUE, protocol is registered, otherwise FALSE.
*/
void
-CopyPasteDnDWrapper::SetIsRegistered(bool isRegistered)
+CopyPasteDnDWrapper::SetCPIsRegistered(bool isRegistered)
{
- m_isRegistered = isRegistered;
+ m_isCPRegistered = isRegistered;
}
+
/**
*
- * Get the flag indication that we are wrapping an initialized and registered
+ * Get the flag indicating that we are wrapping an initialized and registered
* copy paste implementation, or not.
*
- * @return TRUE if copy paste is initialized, otherwise FALSE.
+ * @return TRUE if copy paste is initialized, otherwise FALSE.
*/
bool
-CopyPasteDnDWrapper::IsRegistered()
+CopyPasteDnDWrapper::IsCPRegistered()
{
- return m_isRegistered;
+ return m_isCPRegistered;
+}
+
+
+/**
+ *
+ * Set a flag indicating that we are wrapping an initialized and registered
+ * DnD implementation, or not.
+ *
+ * @param[in] isRegistered If TRUE, protocol is registered, otherwise FALSE.
+ */
+
+void
+CopyPasteDnDWrapper::SetDnDIsRegistered(bool isRegistered)
+{
+ m_isDnDRegistered = isRegistered;
+}
+
+
+/**
+ *
+ * Get the flag indicating that we are wrapping an initialized and registered
+ * DnD implementation, or not.
+ *
+ * @return TRUE if DnD is initialized, otherwise FALSE.
+ */
+
+bool
+CopyPasteDnDWrapper::IsDnDRegistered()
+{
+ return m_isDnDRegistered;
}
CopyPasteDnDWrapper::OnReset()
{
Debug("%s: enter\n", __FUNCTION__);
- if (IsRegistered()) {
- Unregister();
+ if (IsDnDRegistered()) {
+ UnregisterDnD();
+ }
+ if (IsCPRegistered()) {
+ UnregisterCP();
}
- Register();
- if (!IsRegistered()) {
- Debug("%s: unable to reset!\n", __FUNCTION__);
+ RegisterCP();
+ RegisterDnD();
+ if (!IsDnDRegistered() || !IsCPRegistered()) {
+ Debug("%s: unable to reset fully!\n", __FUNCTION__);
}
}
-
/**
* @file copyPasteDnDWrapper.h
- *
+ *
* This singleton class implements a wrapper around various versions of
- * copy and paste.
+ * copy and paste and dnd versions for Linux.
*
*/
#ifndef COPYPASTEDNDWRAPPER_H
#define COPYPASTEDNDWRAPPER_H
+extern "C" {
+#include "dnd.h" /* for DnDBlockControl */
+}
+
#if defined(HAVE_GTKMM)
#include "copyPasteUI.h"
+#include "dndUI.h"
#endif
+#include "vm_basic_types.h"
+#include <gtk/gtk.h>
+
+struct DblLnkLst_Links;
+
+extern "C" {
+void CopyPasteDnDWrapper_SetUnityMode(Bool mode);
+}
+
class CopyPasteDnDWrapper
{
public:
~CopyPasteDnDWrapper();
static CopyPasteDnDWrapper *GetInstance();
- bool Register();
- void Unregister();
- int GetVersion();
- void SetIsRegistered(bool isRegistered);
- bool IsRegistered();
+ bool RegisterCP();
+ void UnregisterCP();
+ bool RegisterDnD();
+ void UnregisterDnD();
+ int GetCPVersion();
+ int GetDnDVersion();
+ void SetCPIsRegistered(bool isRegistered);
+ bool IsCPRegistered();
+ void SetDnDIsRegistered(bool isRegistered);
+ bool IsDnDRegistered();
void OnReset();
- void SetBlockFd(int blockFd);
+ void SetBlockControl(DnDBlockControl *blockCtrl);
void SetUserData(const void *userData);
+ void SetHGWnd(GtkWidget *wnd) {m_hgWnd = wnd;};
+ void SetGHWnd(GtkWidget *wnd) {m_ghWnd = wnd;};
+ void SetEventQueue(DblLnkLst_Links *queue) {m_eventQueue = queue;};
+#if defined(HAVE_GTKMM)
+ void SetUnityMode(Bool mode)
+ {m_dndUI->SetUnityMode(mode);};
+#endif
private:
/*
* We're a singleton, so it is a compile time error to call these.
private:
#if defined(HAVE_GTKMM)
CopyPasteUI *m_copyPasteUI;
+ DnDUI *m_dndUI;
#endif
- bool m_isRegistered;
+ bool m_isCPRegistered;
+ bool m_isDnDRegistered;
const void *m_userData;
- int m_version;
+ int m_cpVersion;
+ int m_dndVersion;
static CopyPasteDnDWrapper *m_instance;
- int mBlockFd;
+ DnDBlockControl *m_blockCtrl;
+ bool m_isLegacy;
+ GtkWidget *m_hgWnd;
+ GtkWidget *m_ghWnd;
+ DblLnkLst_Links *m_eventQueue;
};
#endif // COPYPASTEDNDWRAPPER_H
mHGGetFilesInitiated(false),
mFileTransferDone(false),
mBlockAdded(false),
- mBlockFd(-1),
+ mBlockCtrl(0),
mInited(false)
{
}
void
CopyPasteUI::Init()
{
-
if (mInited) {
return;
}
}
mHGGetFilesInitiated = true;
- if (DnD_AddBlock(mBlockFd, hgStagingDir.c_str())) {
- Debug("%s: add block mBlockFd %d.\n", __FUNCTION__, mBlockFd);
- mHGStagingDir = hgStagingDir;
+ if (DnD_BlockIsReady(mBlockCtrl) && mBlockCtrl->AddBlock(mBlockCtrl->fd, hgStagingDir.c_str())) {
+ Debug("%s: add block for %s.\n",
+ __FUNCTION__, hgStagingDir.c_str());
mBlockAdded = true;
} else {
- Debug("%s: unable to add block fd %d dir %s.\n",
- __FUNCTION__, mBlockFd, hgStagingDir.c_str());
+ Debug("%s: unable to add block for %s.\n",
+ __FUNCTION__, hgStagingDir.c_str());
}
+ mHGStagingDir = hgStagingDir;
+
/* Provide URIs for each path in the guest's file list. */
if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
mHGCopiedUriList = "copy\n";
while ((str = GetNextPath(mHGFCPData, index).c_str()).bytes() != 0) {
Debug("%s: Path: %s", __FUNCTION__, str.c_str());
mHGCopiedUriList += pre;
- mHGCopiedUriList += VMBLOCK_MOUNT_POINT;
- mHGCopiedUriList += DIRSEPS + stagingDirName + DIRSEPS + str + post;
+ if (mBlockAdded) {
+ mHGCopiedUriList += mBlockCtrl->blockRoot;
+ mHGCopiedUriList += DIRSEPS + stagingDirName + DIRSEPS + str + post;
+ } else {
+ mHGCopiedUriList += DIRSEPS + hgStagingDir + DIRSEPS + str + post;
+ }
}
/* Nautilus does not expect FCP_GNOME_LIST_POST after the last uri. See bug 143147. */
* return.
*/
Debug("%s no blocking driver, waiting for "
- "HG file copy done ...\n", __FUNCTION__);
+ "HG file copy done ... mFileTransferDone is %d\n", __FUNCTION__,
+ (int) mFileTransferDone);
while (mFileTransferDone == false) {
struct timeval tv;
int nr;
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CopyPasteUI::LocalGetTextOrRTFRequestCB --
+ *
+ * Callback from a text or RTF paste request from another guest application.
+ * H->G copy paste only.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+CopyPasteUI::LocalGetTextOrRTFRequestCB(Gtk::SelectionData& sd, // IN/OUT
+ guint info) // Ignored
+{
+ if (!mCP.IsCopyPasteAllowed()) {
+ return;
+ }
+
+ const utf::string target = sd.get_target().c_str();
+
+ Debug("%s: Got paste request, target is %s\n",
+ __FUNCTION__, target.c_str());
+
+ if (target == TARGET_NAME_APPLICATION_RTF ||
+ target == TARGET_NAME_TEXT_RICHTEXT) {
+ if (0 == mHGRTFData.bytes()) {
+ Debug("%s: Can not get valid RTF data\n", __FUNCTION__);
+ return;
+ }
+
+ Debug("%s: providing RTF data, size %"FMTSZ"u\n",
+ __FUNCTION__, mHGRTFData.bytes());
+
+ sd.set(target.c_str(), mHGRTFData.c_str());
+ }
+
+ if (target == TARGET_NAME_STRING ||
+ target == TARGET_NAME_TEXT_PLAIN ||
+ target == TARGET_NAME_UTF8_STRING ||
+ target == TARGET_NAME_COMPOUND_TEXT) {
+ if (0 == mHGTextData.bytes()) {
+ Debug("%s: Can not get valid text data\n", __FUNCTION__);
+ return;
+ }
+ Debug("%s: providing plain text, size %"FMTSZ"u\n",
+ __FUNCTION__, mHGTextData.bytes());
+
+ sd.set(target.c_str(), mHGTextData.c_str());
+ }
+}
+
+
/*
*-----------------------------------------------------------------------------
*
void
CopyPasteUI::LocalPrimTimestampCB(const Gtk::SelectionData& sd) // IN
{
- bool unchanged = FALSE;
int length = sd.get_length();
Debug("%s: enter sd.get_length() is %d.\n", __FUNCTION__, length);
if (length == 4) {
if (mClipTime > mPrimTime) {
mGHSelection = GDK_SELECTION_CLIPBOARD;
Debug("%s: mClipTimePrev: %"FMT64"u.", __FUNCTION__, mClipTimePrev);
- unchanged = mClipTime <= mClipTimePrev;
} else {
Debug("%s: mPrimTimePrev: %"FMT64"u.", __FUNCTION__, mPrimTimePrev);
- unchanged = mPrimTime <= mPrimTimePrev;
- }
-
- if (unchanged) {
- Debug("%s: clipboard is unchanged, get out\n", __FUNCTION__);
- CPClipboard_SetChanged(&mClipboard, FALSE);
- return;
}
mPrimTimePrev = mPrimTime;
return;
}
+ /* Try to get image data from clipboard. */
+ Glib::RefPtr<Gdk::Pixbuf> img = refClipboard->wait_for_image();
+ if (img) {
+ gchar *buf = NULL;
+ gsize bufSize;
+
+ img->save_to_buffer(buf, bufSize, Glib::ustring("png"));
+ if (bufSize > 0 &&
+ bufSize <= (int)DNDMSG_MAX_ARGSZ &&
+ CPClipboard_SetItem(&mClipboard, CPFORMAT_IMG_PNG,
+ buf, bufSize)) {
+ mCP.SetRemoteClipboard(&mClipboard);
+ Debug("%s: Got PNG: %"FMTSZ"u\n", __FUNCTION__, bufSize);
+ } else {
+ Debug("%s: Failed to get PNG\n", __FUNCTION__);
+ }
+ g_free(buf);
+ return;
+ }
+
+ /*
+ * Try to get RTF data from local clipboard. 2 targets are supported, and
+ * both share same callback because data is same.
+ */
+ if (std::find(targets.begin(),
+ targets.end(),
+ TARGET_NAME_APPLICATION_RTF) != targets.end()) {
+ Debug("%s: TARGET_NAME_APPLICATION_RTF available\n", __FUNCTION__);
+ refClipboard->request_contents(TARGET_NAME_APPLICATION_RTF,
+ sigc::mem_fun(this,
+ &CopyPasteUI::LocalReceivedRTFCB));
+ return;
+ }
+
+ if (std::find(targets.begin(),
+ targets.end(),
+ TARGET_NAME_TEXT_RICHTEXT) != targets.end()) {
+ Debug("%s: TARGET_NAME_TEXT_RICHTEXT available\n", __FUNCTION__);
+ refClipboard->request_contents(TARGET_NAME_TEXT_RICHTEXT,
+ sigc::mem_fun(this,
+ &CopyPasteUI::LocalReceivedRTFCB));
+ return;
+ }
+
Debug("%s: ask for text\n", __FUNCTION__);
refClipboard->request_text(sigc::mem_fun(this,
&CopyPasteUI::LocalReceivedTextCB));
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * CopyPasteUI::LocalReceivedRTFCB --
+ *
+ * Got clipboard (or primary selection) RTF text, add to local
+ * clipboard cache and send clipboard to host.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+CopyPasteUI::LocalReceivedRTFCB(const Gtk::SelectionData& sd) // IN
+{
+ utf::string source = sd.get_data_as_string().c_str();
+ Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get(mGHSelection);
+
+ /* Add NUL terminator. */
+ if (source.bytes() > 0 &&
+ source.bytes() < DNDMSG_MAX_ARGSZ &&
+ CPClipboard_SetItem(&mClipboard, CPFORMAT_RTF, source.c_str(),
+ source.bytes() + 1)) {
+ Debug("%s: Got RTF, size %"FMTSZ"u\n", __FUNCTION__, source.bytes());
+ } else {
+ Debug("%s: Failed to get RTF\n", __FUNCTION__);
+ }
+
+ /*
+ * Still should try to get plain text. LocalReceivedTextCB will send data
+ * to guest.
+ */
+ Debug("%s: ask for text\n", __FUNCTION__);
+ refClipboard->request_text(sigc::mem_fun(this,
+ &CopyPasteUI::LocalReceivedTextCB));
+}
+
+
/*
*----------------------------------------------------------------------
*
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CopyPasteUI::LocalGetFileContentsRequestCB --
+ *
+ * Callback from a file paste request from another guest application.
+ * Return the file list.
+ *
+ * H->G only.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+CopyPasteUI::LocalGetFileContentsRequestCB(Gtk::SelectionData& sd, // IN
+ guint info) // IN
+{
+ std::vector<utf::string>::const_iterator iter;
+ utf::string uriList = "";
+ utf::string pre;
+ utf::string post;
+
+ /* Provide URIs for each path in the guest's file list. */
+ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
+ uriList = "copy\n";
+ pre = FCP_GNOME_LIST_PRE;
+ post = FCP_GNOME_LIST_POST;
+ } else if (FCP_TARGET_INFO_URI_LIST == info) {
+ pre = DND_URI_LIST_PRE_KDE;
+ post = DND_URI_LIST_POST;
+ } else {
+ Debug("%s: Unknown request target: %s\n",
+ __FUNCTION__, sd.get_target().c_str());
+ return;
+ }
+
+ for (iter = mHGFileContentsList.begin();
+ iter != mHGFileContentsList.end();
+ iter++) {
+ uriList += pre + *iter + post;
+ }
+
+ /* Nautilus does not expect FCP_GNOME_LIST_POST after the last uri. See bug 143147. */
+ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
+ uriList.erase(uriList.size() - 1, 1);
+ }
+
+ if (0 == uriList.bytes()) {
+ Debug("%s: Can not get uri list\n", __FUNCTION__);
+ return;
+ }
+
+ Debug("%s: providing file list [%s]\n", __FUNCTION__, uriList.c_str());
+
+ sd.set(sd.get_target().c_str(), uriList.c_str());
+}
+
+
/*
*-----------------------------------------------------------------------------
*
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CopyPasteUI::GetLastDirName --
+ *
+ * Try to get last directory name from a full path name.
+ *
+ * Results:
+ * Last dir name in the full path name if sucess, empty str otherwise
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+utf::string
+CopyPasteUI::GetLastDirName(const utf::string &str) // IN
+{
+ utf::string ret;
+ size_t start;
+ size_t end;
+
+ end = str.bytes() - 1;
+ if (end >= 0 && DIRSEPC == str[end]) {
+ end--;
+ }
+
+ if (end <= 0 || str[0] != DIRSEPC) {
+ return "";
+ }
+
+ start = end;
+
+ while (str[start] != DIRSEPC) {
+ start--;
+ }
+
+ return str.substr(start + 1, end - start);
+}
+
+
/*
*----------------------------------------------------------------------------
*
}
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::GetLastDirName --
- *
- * Try to get last directory name from a full path name.
- *
- * Results:
- * Last dir name in the full path name if sucess, empty str otherwise
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-utf::string
-CopyPasteUI::GetLastDirName(const utf::string &str) // IN
-{
- utf::string ret;
- size_t start;
- size_t end;
-
- end = str.bytes() - 1;
- if (end >= 0 && DIRSEPC == str[end]) {
- end--;
- }
-
- if (end <= 0 || str[0] != DIRSEPC) {
- return "";
- }
-
- start = end;
-
- while (str[start] != DIRSEPC) {
- start--;
- }
-
- return str.substr(start + 1, end - start);
-}
-
/*
*-----------------------------------------------------------------------------
*
Debug("%s: Cleared local clipboard", __FUNCTION__);
}
- if (CPClipboard_GetItem(clip, CPFORMAT_TEXT, &buf, &sz)) {
- Debug("%s: Text data: %s.\n", __FUNCTION__, (char *)buf);
- refClipboard->set_text((const char *) buf);
- refPrimary->set_text((const char *) buf);
+ mHGTextData.clear();
+ mHGRTFData.clear();
+ mHGFCPData.clear();
+
+ if (CPClipboard_ItemExists(clip, CPFORMAT_TEXT) ||
+ CPClipboard_ItemExists(clip, CPFORMAT_RTF)) {
+ std::list<Gtk::TargetEntry> targets;
+
+ if (CPClipboard_GetItem(clip, CPFORMAT_TEXT, &buf, &sz)) {
+ Gtk::TargetEntry stringText(TARGET_NAME_STRING);
+ Gtk::TargetEntry plainText(TARGET_NAME_TEXT_PLAIN);
+ Gtk::TargetEntry utf8Text(TARGET_NAME_UTF8_STRING);
+ Gtk::TargetEntry compountText(TARGET_NAME_COMPOUND_TEXT);
+
+ Debug("%s: Text data, size %"FMTSZ"u.\n", __FUNCTION__, sz);
+ targets.push_back(stringText);
+ targets.push_back(plainText);
+ targets.push_back(utf8Text);
+ targets.push_back(compountText);
+ mHGTextData = utf::string((const char *)buf);
+
+ mIsClipboardOwner = TRUE;
+ }
+
+ if (CPClipboard_GetItem(clip, CPFORMAT_RTF, &buf, &sz)) {
+ Debug("%s: RTF data, size %"FMTSZ"u.\n", __FUNCTION__, sz);
+ Gtk::TargetEntry appRtf(TARGET_NAME_APPLICATION_RTF);
+ Gtk::TargetEntry textRtf(TARGET_NAME_TEXT_RICHTEXT);
+
+ targets.push_back(appRtf);
+ targets.push_back(textRtf);
+ mHGRTFData = utf::string((const char *)buf);
+
+ mIsClipboardOwner = TRUE;
+ }
+
+ refClipboard->set(targets,
+ sigc::mem_fun(this, &CopyPasteUI::LocalGetTextOrRTFRequestCB),
+ sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
+ refPrimary->set(targets,
+ sigc::mem_fun(this, &CopyPasteUI::LocalGetTextOrRTFRequestCB),
+ sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
+ return;
+ }
+
+ if (CPClipboard_GetItem(clip, CPFORMAT_IMG_PNG, &buf, &sz)) {
+ Debug("%s: PNG data, size %"FMTSZ"u.\n", __FUNCTION__, sz);
+ /* Try to load buf into pixbuf, and write to local clipboard. */
+ Glib::RefPtr<Gdk::PixbufLoader> loader = Gdk::PixbufLoader::create();
+
+ if (loader) {
+ loader->write((const guint8 *)buf, sz);
+ loader->close();
+
+ refClipboard->set_image(loader->get_pixbuf());
+ refPrimary->set_image(loader->get_pixbuf());
+ }
+ return;
}
if (CPClipboard_GetItem(clip, CPFORMAT_FILELIST, &buf, &sz)) {
Debug("%s: File data.\n", __FUNCTION__);
mHGGetFilesInitiated = false;
mHGCopiedUriList = "";
}
+
+ if (CPClipboard_ItemExists(clip, CPFORMAT_FILECONTENTS)) {
+ Debug("%s: File contents data\n", __FUNCTION__);
+ if (LocalPrepareFileContents(clip)) {
+ refClipboard->set(mListTargets,
+ sigc::mem_fun(this, &CopyPasteUI::LocalGetFileContentsRequestCB),
+ sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
+ refPrimary->set(mListTargets,
+ sigc::mem_fun(this, &CopyPasteUI::LocalGetFileContentsRequestCB),
+ sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
+ mIsClipboardOwner = TRUE;
+ }
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * CopyPasteUI::LocalPrepareFileContents --
+ *
+ * Try to extract file contents from mClipboard. Write all files to a
+ * temporary staging directory. Construct uri list.
+ *
+ * Results:
+ * true if success, false otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+bool
+CopyPasteUI::LocalPrepareFileContents(const CPClipboard *clip) // IN
+{
+ void *buf = NULL;
+ size_t sz = 0;
+ XDR xdrs;
+ CPFileContents fileContents;
+ CPFileContentsList *contentsList = NULL;
+ size_t nFiles = 0;
+ CPFileItem *fileItem = NULL;
+ Unicode tempDir = NULL;
+ size_t i = 0;
+ bool ret = false;
+
+ if (!CPClipboard_GetItem(clip, CPFORMAT_FILECONTENTS, &buf, &sz)) {
+ Debug("%s: CPClipboard_GetItem failed\n", __FUNCTION__);
+ return false;
+ }
+
+ /* Extract file contents from buf. */
+ xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE);
+ memset(&fileContents, 0, sizeof fileContents);
+
+ if (!xdr_CPFileContents(&xdrs, &fileContents)) {
+ Debug("%s: xdr_CPFileContents failed.\n", __FUNCTION__);
+ xdr_destroy(&xdrs);
+ return false;
+ }
+ xdr_destroy(&xdrs);
+
+ contentsList = fileContents.CPFileContents_u.fileContentsV1;
+ if (!contentsList) {
+ Debug("%s: invalid contentsList.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ nFiles = contentsList->fileItem.fileItem_len;
+ if (0 == nFiles) {
+ Debug("%s: invalid nFiles.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ fileItem = contentsList->fileItem.fileItem_val;
+ if (!fileItem) {
+ Debug("%s: invalid fileItem.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /*
+ * Write files into a temporary staging directory. These files will be moved
+ * to final destination, or deleted on next reboot.
+ */
+ tempDir = DnD_CreateStagingDirectory();
+ if (!tempDir) {
+ Debug("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ mHGFileContentsList.clear();
+
+ for (i = 0; i < nFiles; i++) {
+ utf::string fileName;
+ utf::string filePathName;
+ VmTimeType createTime = -1;
+ VmTimeType accessTime = -1;
+ VmTimeType writeTime = -1;
+ VmTimeType attrChangeTime = -1;
+
+ if (!fileItem[i].cpName.cpName_val ||
+ 0 == fileItem[i].cpName.cpName_len) {
+ Debug("%s: invalid fileItem[%"FMTSZ"u].cpName.\n", __FUNCTION__, i);
+ goto exit;
+ }
+
+ /*
+ * '\0' is used as directory separator in cross-platform name. Now turn
+ * '\0' in data into DIRSEPC.
+ *
+ * Note that we don't convert the final '\0' into DIRSEPC so the string
+ * is NUL terminated.
+ */
+ CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val,
+ fileItem[i].cpName.cpName_len - 1,
+ '\0',
+ DIRSEPC);
+ fileName = fileItem[i].cpName.cpName_val;
+ filePathName = tempDir;
+ filePathName += DIRSEPS + fileName;
+
+ if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
+ CP_FILE_TYPE_DIRECTORY == fileItem[i].type) {
+ if (!File_CreateDirectory(filePathName.c_str())) {
+ goto exit;
+ }
+ Debug("%s: created directory [%s].\n",
+ __FUNCTION__, filePathName.c_str());
+ } else if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
+ CP_FILE_TYPE_REGULAR == fileItem[i].type) {
+ FileIODescriptor file;
+ FileIOResult fileErr;
+
+ FileIO_Invalidate(&file);
+
+ fileErr = FileIO_Open(&file,
+ filePathName.c_str(),
+ FILEIO_ACCESS_WRITE,
+ FILEIO_OPEN_CREATE_EMPTY);
+ if (!FileIO_IsSuccess(fileErr)) {
+ goto exit;
+ }
+
+ fileErr = FileIO_Write(&file,
+ fileItem[i].content.content_val,
+ fileItem[i].content.content_len,
+ NULL);
+
+ FileIO_Close(&file);
+ Debug("%s: created file [%s].\n", __FUNCTION__, filePathName.c_str());
+ } else {
+ /*
+ * Right now only Windows can provide CPFORMAT_FILECONTENTS data.
+ * Symlink file is not expected. Continue with next file if the
+ * type is not valid.
+ */
+ continue;
+ }
+
+ /* Update file time attributes. */
+ createTime = fileItem->validFlags & CP_FILE_VALID_CREATE_TIME ?
+ fileItem->createTime: -1;
+ accessTime = fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME ?
+ fileItem->accessTime: -1;
+ writeTime = fileItem->validFlags & CP_FILE_VALID_WRITE_TIME ?
+ fileItem->writeTime: -1;
+ attrChangeTime = fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME ?
+ fileItem->attrChangeTime: -1;
+
+ if (!File_SetTimes(filePathName.c_str(),
+ createTime,
+ accessTime,
+ writeTime,
+ attrChangeTime)) {
+ /* Not a critical error, only log it. */
+ Debug("%s: File_SetTimes failed with file [%s].\n",
+ __FUNCTION__, filePathName.c_str());
+ }
+
+ /* Update file permission attributes. */
+ if (fileItem->validFlags & CP_FILE_VALID_PERMS) {
+ if (Posix_Chmod(filePathName.c_str(),
+ fileItem->permissions) < 0) {
+ /* Not a critical error, only log it. */
+ Debug("%s: Posix_Chmod failed with file [%s].\n",
+ __FUNCTION__, filePathName.c_str());
+ }
+ }
+
+ /*
+ * If there is no DIRSEPC inside the fileName, this file/directory is a
+ * top level one. We only put top level name into uri list.
+ */
+ if (fileName.find(DIRSEPS, 0) == utf::string::npos) {
+ mHGFileContentsList.push_back(filePathName);
+ }
+ }
+ Debug("%s: created uri list\n", __FUNCTION__);
+ ret = true;
+
+exit:
+ xdr_free((xdrproc_t)xdr_CPFileContents, (char *)&fileContents);
+ if (tempDir && !ret) {
+ DnD_DeleteStagingFiles(tempDir, FALSE);
+ }
+ free(tempDir);
+ return ret;
}
Debug("%s: enter success %d\n", __FUNCTION__, success);
if (mBlockAdded) {
- Debug("%s: removing block mBlockFd %d\n", __FUNCTION__, mBlockFd);
- DnD_RemoveBlock(mBlockFd, mHGStagingDir.c_str());
+ Debug("%s: removing block for %s\n", __FUNCTION__, mHGStagingDir.c_str());
+ mBlockCtrl->RemoveBlock(mBlockCtrl->fd, mHGStagingDir.c_str());
mBlockAdded = false;
}
#include "stringxx/string.hh"
extern "C" {
- #include "dnd.h"
- #include "debug.h"
- #include "str.h"
+#include "dnd.h"
+#include "debug.h"
+#include "str.h"
+#include "dndClipboard.h"
+#include "dynbuf.h"
+#include "../dnd/dndFileContentsUtil.h"
+#include "dynxdr.h"
+#include "cpNameUtil.h"
+#include "posix.h"
}
#include "unicodeOperations.h"
#include <gtkmm.h>
#include <list>
+#include <vector>
class CopyPasteUI : public sigc::trackable
{
void SetCopyPasteAllowed(bool isCopyPasteAllowed)
{ mCP.SetCopyPasteAllowed(isCopyPasteAllowed); }
void Reset(void);
- void SetBlockFd(int fd) {Debug("Setting mBlockFd to %d\n", fd); mBlockFd = fd;};
+ void SetBlockControl(DnDBlockControl *blockCtrl)
+ { Debug("Setting mBlockCtrl to %p\n", blockCtrl);
+ mBlockCtrl = blockCtrl; }
+
private:
/* hg */
void GetRemoteClipboardCB(const CPClipboard *clip);
void RemoteGetFilesDone(void);
void LocalGetFileRequestCB(Gtk::SelectionData& selection_data, guint info);
+ void LocalGetTextOrRTFRequestCB(Gtk::SelectionData& sd, guint info);
+ void LocalGetSelectionFileList(const Gtk::SelectionData& sd);
+ void LocalGetFileContentsRequestCB(Gtk::SelectionData& sd, guint info);
void LocalClearClipboardCB(void);
/* gh */
void LocalPrimTimestampCB(const Gtk::SelectionData& sd);
void LocalReceivedTargetsCB(const Glib::StringArrayHandle& targets_array);
void LocalReceivedFileListCB(const Gtk::SelectionData& selection_data);
+ void LocalReceivedRTFCB(const Gtk::SelectionData& selection_data);
void LocalReceivedTextCB(const Glib::ustring& text);
void GetLocalFilesDone(bool success);
/* Conversion methods. */
- void LocalGetSelectionFileList(const Gtk::SelectionData& sd);
utf::utf8string GetNextPath(utf::utf8string &str, size_t& index);
utf::string GetLastDirName(const utf::string &str);
+ bool LocalPrepareFileContents(const CPClipboard *clip);
VmTimeType GetCurrentTime(void);
VmTimeType mHGGetListTime;
utf::string mHGCopiedUriList;
utf::utf8string mHGFCPData;
+ utf::string mHGTextData;
+ utf::string mHGRTFData;
+ std::vector<utf::string> mHGFileContentsList;
bool mFileTransferDone;
bool mBlockAdded;
- int mBlockFd;
+ DnDBlockControl *mBlockCtrl;
bool mInited;
};
"bad clientData passed to callback", FALSE);
}
- if (gBlockFd < 0) {
+ if (!DnD_BlockIsReady(&gBlockCtrl)) {
Debug("DnDRpcInEnterCB: cannot allow H->G DnD without vmblock.\n");
return RpcIn_SetRetVals(result, resultLen,
"blocking file system unavailable", FALSE);
Debug("DnDRpcInDataSetCB: enter\n");
- if (gBlockFd < 0) {
+ if (!DnD_BlockIsReady(&gBlockCtrl)) {
Debug("DnDRpcInDataSetCB: blocking file system not available.\n");
return RpcIn_SetRetVals(result, resultLen,
"blocking file system not available", FALSE);
goto out;
}
- if (sizeof VMBLOCK_MOUNT_POINT - 1 +
+ if (strlen(gBlockCtrl.blockRoot) +
(sizeof DIRSEPS - 1) * 2 + strlen(perDnDDir) >= sizeof blockDir) {
Debug("DnDRpcInDataSetCB: blocking directory path too large.\n");
retStr = "blocking directory path too large";
}
Str_Sprintf(blockDir, sizeof blockDir,
- VMBLOCK_MOUNT_POINT DIRSEPS "%s" DIRSEPS, perDnDDir);
+ "%s" DIRSEPS "%s" DIRSEPS, gBlockCtrl.blockRoot, perDnDDir);
/* Add the file root to the relative paths received from host */
if (!DnD_PrependFileRoot(blockDir, &data, &dataSize)) {
free(state);
- if (gBlockFd >= 0 && !DnD_RemoveBlock(gBlockFd, gFileRoot)) {
+ if (DnD_BlockIsReady(&gBlockCtrl) &&
+ !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
Warning("DnDRpcInDataFinishCB: could not remove block on %s\n",
gFileRoot);
}
* release. Make sure we'll succeed before modifying any mouse state in the
* guest.
*/
- if (gBlockFd < 0) {
+ if (!DnD_BlockIsReady(&gBlockCtrl)) {
/*
* We shouldn't get here since DnDRpcInEnterCB() checks this, but we'll
* check rather than ASSERT just in case.
"blocking file system unavailable", FALSE);
}
- if (!DnD_AddBlock(gBlockFd, gFileRoot)) {
+ if (!gBlockCtrl.AddBlock(gBlockCtrl.fd, gFileRoot)) {
return RpcIn_SetRetVals(result, resultLen, "could not add block", FALSE);
}
/* Cancel file transfer. */
if (gHGDnDInProgress || gHGDataPending) {
DnD_DeleteStagingFiles(gFileRoot, FALSE);
- if (gBlockFd >= 0 && !DnD_RemoveBlock(gBlockFd, gFileRoot)) {
+ if (DnD_BlockIsReady(&gBlockCtrl) &&
+ !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
Warning("DnD_OnReset: could not remove block on %s\n",
gFileRoot);
}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/**
+ * @file dndUI.cpp --
+ *
+ * This class implements stubs for the methods that allow DnD between
+ * host and guest.
+ */
+
+#include "dndUI.h"
+
+extern "C" {
+#include "vmwareuserInt.h"
+#include "vmblock.h"
+#include "vm_app.h"
+#include "file.h"
+#include "dnd.h"
+#include "dndMsg.h"
+#include "dndClipboard.h"
+#include "cpName.h"
+#include "debug.h"
+#include "cpNameUtil.h"
+#include "rpcout.h"
+#include "eventManager.h"
+#include "unity.h"
+#include <gtk/gtk.h>
+#include <X11/extensions/XTest.h> /* for XTest*() */
+}
+
+#include "dndGuest.h"
+#include "copyPasteDnDWrapper.h"
+
+/**
+ *
+ * Constructor.
+ */
+
+DnDUI::DnDUI(DblLnkLst_Links *eventQueue)
+ : m_eventQueue(eventQueue),
+ m_DnD(NULL),
+ m_detWnd(NULL),
+ m_detWndFull(NULL),
+ m_blockCtrl(NULL),
+ m_HGGetDataInProgress(false),
+ m_blockAdded(false),
+ m_GHDnDInProgress(false),
+ m_GHDnDHostStatus(false),
+ m_GHDnDAction((Gdk::DragAction)0),
+ m_GHDnDDataReceived(false),
+ m_GHDnDDropOccurred(false),
+ m_VMIsSource(false),
+ m_unityMode(false),
+ m_inHGDrag(false),
+ m_effect(DROP_UNKNOWN),
+ m_needsBlock(false),
+ m_isFileDnD(false)
+{
+ Debug("%s: enter\n", __FUNCTION__);
+}
+
+
+/**
+ *
+ * Destructor.
+ */
+
+DnDUI::~DnDUI()
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ Reset();
+ if (m_DnD) {
+ delete m_DnD;
+ }
+ if (m_detWnd) {
+ delete m_detWnd;
+ }
+ if (m_detWndFull) {
+ delete m_detWndFull;
+ }
+ m_feedbackChanged.disconnect();
+ CPClipboard_Destroy(&m_clipboard);
+}
+
+
+/**
+ *
+ * Initialize DnDUI object.
+ */
+
+void
+DnDUI::Init()
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ char *reply = NULL;
+ size_t replyLen;
+
+ ASSERT(m_eventQueue);
+ CPClipboard_Init(&m_clipboard);
+ m_DnD = new DnD(m_eventQueue);
+ if (!m_DnD) {
+ Debug("%s: unable to allocate DnD object\n", __FUNCTION__);
+ goto fail;
+ }
+ m_detWnd = new DragDetWnd();
+ if (!m_detWnd) {
+ Debug("%s: unable to allocate DragDetWnd object\n", __FUNCTION__);
+ goto fail;
+ }
+ m_detWndFull = new DragDetWnd();
+ if (!m_detWndFull) {
+ Debug("%s: unable to allocate DragDetWnd object\n", __FUNCTION__);
+ goto fail;
+ }
+
+#if defined(DETWNDDEBUG)
+
+ /*
+ * This code can only be called when DragDetWnd is derived from
+ * Gtk::Window. The normal case is that DragDetWnd is an instance of
+ * Gtk::Invisible, which doesn't implement the methods that SetAttributes
+ * relies upon.
+ */
+
+ m_detWnd->SetAttributes();
+ m_detWndFull->SetAttributes();
+#endif
+
+ SetTargetsAndCallbacks();
+
+ /* Exchange dnd version information with the VMX */
+ if (!RpcOut_sendOne(NULL, NULL, "tools.capability.dnd_version 3")) {
+ Debug("%s: could not set guest dnd version capability\n", __FUNCTION__);
+ goto fail;
+ } else {
+ if (!RpcOut_sendOne(&reply, &replyLen, "vmx.capability.dnd_version")) {
+ Debug("%s: could not get VMX dnd version capability\n",
+ __FUNCTION__);
+ goto fail;
+ } else if (atoi(reply) < 3) {
+ Debug("%s: VMX DnD version is less than 3.\n", __FUNCTION__);
+ goto fail;
+ }
+ }
+
+ Debug("%s: VMX version ok: %d\n", __FUNCTION__, atoi(reply));
+
+ m_DnD->reset.connect(sigc::mem_fun(this, &DnDUI::ResetUIStateCB));
+ m_DnD->dragStartChanged.connect(
+ sigc::mem_fun(this, &DnDUI::RemoteDragStartCB));
+ m_DnD->fileCopyDoneChanged.connect(
+ sigc::mem_fun(this, &DnDUI::GetLocalFilesDoneCB));
+ m_DnD->updateDetWndChanged.connect(
+ sigc::mem_fun(this, &DnDUI::UpdateDetWndCB));
+ m_DnD->updateUnityDetWndChanged.connect(
+ sigc::mem_fun(this, &DnDUI::UpdateUnityDetWndCB));
+ m_DnD->sourceCancelChanged.connect(
+ sigc::mem_fun(this, &DnDUI::SourceCancelCB));
+ m_DnD->sourceDropChanged.connect(
+ sigc::mem_fun(this, &DnDUI::SourceDropCB));
+
+ m_detWnd->signal_drag_data_get().connect(
+ sigc::mem_fun(this, &DnDUI::LocalDragDataGetCB));
+ m_detWnd->signal_drag_end().connect(
+ sigc::mem_fun(this, &DnDUI::LocalDragEndCB));
+ m_detWnd->signal_drag_drop().connect(
+ sigc::mem_fun(this, &DnDUI::LocalDragDropCB));
+
+ UpdateDetWndCB(false, 0, 0);
+ UpdateUnityDetWndCB(false, 0);
+ goto out;
+fail:
+ if (m_DnD) {
+ delete m_DnD;
+ }
+ if (m_detWnd) {
+ delete m_detWnd;
+ }
+ if (m_detWndFull) {
+ delete m_detWndFull;
+ }
+out:
+ if (reply) {
+ free(reply);
+ }
+ return;
+}
+
+
+/**
+ *
+ * Setup targets we support, claim ourselves as a drag destination, and
+ * register callbacks for Gdk drag and drop callbacks the platform will
+ * send to us.
+ */
+
+void
+DnDUI::SetTargetsAndCallbacks()
+{
+ Debug("%s: enter\n", __FUNCTION__);
+
+ /* Construct supported target list for HG DnD. */
+ std::list<Gtk::TargetEntry> targets;
+
+ /* File DnD. */
+ targets.push_back(Gtk::TargetEntry(DRAG_TARGET_NAME_URI_LIST));
+
+ /* RTF text DnD. */
+ targets.push_back(Gtk::TargetEntry(TARGET_NAME_APPLICATION_RTF));
+ targets.push_back(Gtk::TargetEntry(TARGET_NAME_TEXT_RICHTEXT));
+
+ /* Plain text DnD. */
+ targets.push_back(Gtk::TargetEntry(TARGET_NAME_STRING));
+ targets.push_back(Gtk::TargetEntry(TARGET_NAME_TEXT_PLAIN));
+ targets.push_back(Gtk::TargetEntry(TARGET_NAME_UTF8_STRING));
+ targets.push_back(Gtk::TargetEntry(TARGET_NAME_COMPOUND_TEXT));
+
+ /*
+ * We don't want Gtk handling any signals for us, we want to
+ * do it ourselves based on the results from the guest.
+ *
+ * Second argument in drag_dest_set defines the automatic behaviour options
+ * of the destination widget. We used to not define it (0) and in some
+ * distributions (like Ubuntu 6.10) DragMotion only get called once,
+ * and not send updated mouse position to guest, and also got cancel
+ * signal when user drop the file (bug 175754). With flag DEST_DEFAULT_MOTION
+ * the bug is fixed. Almost all other example codes use DEST_DEFAULT_ALL
+ * but in our case, we will call drag_get_data during DragMotion, and
+ * will cause X dead with DEST_DEFAULT_ALL. The reason is unclear.
+ */
+ m_detWnd->drag_dest_set(targets, Gtk::DEST_DEFAULT_MOTION,
+ Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
+ m_detWnd->signal_drag_leave().connect(sigc::mem_fun(this, &DnDUI::LocalDragLeaveCB));
+ m_detWnd->signal_drag_motion().connect(sigc::mem_fun(this, &DnDUI::LocalDragMotionCB));
+ m_detWnd->signal_drag_drop().connect(sigc::mem_fun(this, &DnDUI::LocalDragDropCB));
+ m_detWnd->signal_drag_data_received().connect(sigc::mem_fun(this, &DnDUI::LocalDragDataReceivedCB));
+}
+
+
+/**
+ *
+ * Reset Callback to reset dnd ui state.
+ */
+
+void
+DnDUI::ResetUIStateCB(void)
+{
+ m_GHDnDHostStatus = false;
+ m_GHDnDAction = (Gdk::DragAction)0;
+ m_GHDnDDataReceived = false;
+ m_GHDnDDropOccurred = false;
+ m_HGGetDataInProgress = false;
+ m_VMIsSource = false;
+ m_GHDnDInProgress = false;
+ m_feedbackChanged.disconnect();
+ m_effect = DROP_UNKNOWN;
+ RemoveBlock();
+}
+
+
+/**
+ * Set block control member.
+ *
+ * @param[in] block control as setup by vmware-user.
+ */
+
+void
+DnDUI::SetBlockControl(DnDBlockControl *blockCtrl)
+{
+ m_blockCtrl = blockCtrl;
+}
+
+/* Source functions for HG DnD. */
+
+/**
+ *
+ * Called when host successfully detected a pending HG drag.
+ *
+ * param[in] clip cross-platform clipboard
+ * param[in] stagingDir associated staging directory
+ */
+
+void
+DnDUI::RemoteDragStartCB(const CPClipboard *clip, std::string stagingDir)
+{
+ Glib::RefPtr<Gtk::TargetList> targets;
+ Gdk::DragAction actions;
+ GdkEventMotion event;
+
+ CPClipboard_Clear(&m_clipboard);
+ CPClipboard_Copy(&m_clipboard, clip);
+
+ Debug("%s: enter\n", __FUNCTION__);
+
+ /*
+ * Construct the target and action list, as well as a fake motion notify
+ * event that's consistent with one that would typically start a drag.
+ */
+ targets = Gtk::TargetList::create(std::list<Gtk::TargetEntry>());
+
+ if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILELIST)) {
+ m_HGStagingDir = stagingDir;
+ if (!m_HGStagingDir.empty()) {
+ targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST));
+ /* Add private data to tag dnd as originating from this vm. */
+ char *pid;
+ Debug("%s: adding re-entrant drop target, pid %d\n", __FUNCTION__, getpid());
+ pid = Str_Asprintf(NULL, "guest-dnd-target %d", static_cast<int>(getpid()));
+ if (pid) {
+ targets->add(Glib::ustring(pid));
+ free(pid);
+ }
+ }
+ }
+
+ if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILECONTENTS)) {
+ if (LocalPrepareFileContentsDrag()) {
+ targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST));
+ }
+ }
+
+ if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_TEXT)) {
+ targets->add(Glib::ustring(TARGET_NAME_STRING));
+ targets->add(Glib::ustring(TARGET_NAME_TEXT_PLAIN));
+ targets->add(Glib::ustring(TARGET_NAME_UTF8_STRING));
+ targets->add(Glib::ustring(TARGET_NAME_COMPOUND_TEXT));
+ }
+
+ if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_RTF)) {
+ targets->add(Glib::ustring(TARGET_NAME_APPLICATION_RTF));
+ targets->add(Glib::ustring(TARGET_NAME_TEXT_RICHTEXT));
+ }
+
+ actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE;
+
+ /* TODO set the x/y coords to the actual drag initialization point. */
+ event.type = GDK_MOTION_NOTIFY;
+ event.window = m_detWnd->get_window()->gobj();
+ event.send_event = FALSE;
+ event.time = GDK_CURRENT_TIME;
+ event.x = 10;
+ event.y = 10;
+ event.axes = NULL;
+ event.state = GDK_BUTTON1_MASK;
+ event.is_hint = 0;
+ event.device = gdk_device_get_core_pointer();
+ event.x_root = 0;
+ event.y_root = 5;
+
+ /* Tell Gtk that a drag should be started from this widget. */
+ m_detWnd->drag_begin(targets, actions, 1, (GdkEvent *)&event);
+ m_blockAdded = false;
+ m_needsBlock = false;
+ m_isFileDnD = false;
+ SourceDragStartDone();
+}
+
+
+/**
+ *
+ * Try to extract file contents from m_clipboard. Write all files to a
+ * temporary staging directory. Construct uri list.
+ *
+ * @return TRUE if success, FALSE otherwise.
+ */
+
+bool
+DnDUI::LocalPrepareFileContentsDrag(void)
+{
+ void *buf = NULL;
+ size_t sz = 0;
+ XDR xdrs;
+ CPFileContents fileContents;
+ CPFileContentsList *contentsList = NULL;
+ size_t nFiles = 0;
+ CPFileItem *fileItem = NULL;
+ Unicode tempDir = NULL;
+ size_t i = 0;
+ bool ret = FALSE;
+
+ if (!CPClipboard_GetItem(&m_clipboard, CPFORMAT_FILECONTENTS, &buf, &sz)) {
+ return false;
+ }
+
+ /* Extract file contents from buf. */
+ xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE);
+ memset(&fileContents, 0, sizeof fileContents);
+
+ if (!xdr_CPFileContents(&xdrs, &fileContents)) {
+ Debug("%s: xdr_CPFileContents failed.\n", __FUNCTION__);
+ xdr_destroy(&xdrs);
+ return false;
+ }
+ xdr_destroy(&xdrs);
+
+ contentsList = fileContents.CPFileContents_u.fileContentsV1;
+ if (!contentsList) {
+ Debug("%s: invalid contentsList.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ nFiles = contentsList->fileItem.fileItem_len;
+ if (0 == nFiles) {
+ Debug("%s: invalid nFiles.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ fileItem = contentsList->fileItem.fileItem_val;
+ if (!fileItem) {
+ Debug("%s: invalid fileItem.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /*
+ * Write files into a temporary staging directory. These files will be moved
+ * to final destination, or deleted on next reboot.
+ */
+ tempDir = DnD_CreateStagingDirectory();
+ if (!tempDir) {
+ Debug("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__);
+ goto exit;
+ }
+
+ m_HGFileContentsUriList = "";
+
+ for (i = 0; i < nFiles; i++) {
+ utf::string fileName;
+ utf::string filePathName;
+ VmTimeType createTime = -1;
+ VmTimeType accessTime = -1;
+ VmTimeType writeTime = -1;
+ VmTimeType attrChangeTime = -1;
+
+ if (!fileItem[i].cpName.cpName_val ||
+ 0 == fileItem[i].cpName.cpName_len) {
+ Debug("%s: invalid fileItem[%"FMTSZ"u].cpName.\n", __FUNCTION__, i);
+ goto exit;
+ }
+
+ /*
+ * '\0' is used as directory separator in cross-platform name. Now turn
+ * '\0' in data into DIRSEPC.
+ *
+ * Note that we don't convert the final '\0' into DIRSEPC so the string
+ * is NUL terminated.
+ */
+ CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val,
+ fileItem[i].cpName.cpName_len - 1,
+ '\0',
+ DIRSEPC);
+ fileName = fileItem[i].cpName.cpName_val;
+ filePathName = tempDir;
+ filePathName += DIRSEPS + fileName;
+
+ if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
+ CP_FILE_TYPE_DIRECTORY == fileItem[i].type) {
+ if (!File_CreateDirectory(filePathName.c_str())) {
+ goto exit;
+ }
+ Debug("%s: created directory [%s].\n",
+ __FUNCTION__, filePathName.c_str());
+ } else if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
+ CP_FILE_TYPE_REGULAR == fileItem[i].type) {
+ FileIODescriptor file;
+ FileIOResult fileErr;
+
+ FileIO_Invalidate(&file);
+
+ fileErr = FileIO_Open(&file,
+ filePathName.c_str(),
+ FILEIO_ACCESS_WRITE,
+ FILEIO_OPEN_CREATE_EMPTY);
+ if (!FileIO_IsSuccess(fileErr)) {
+ goto exit;
+ }
+
+ fileErr = FileIO_Write(&file,
+ fileItem[i].content.content_val,
+ fileItem[i].content.content_len,
+ NULL);
+
+ FileIO_Close(&file);
+ Debug("%s: created file [%s].\n",
+ __FUNCTION__, filePathName.c_str());
+ } else {
+ /*
+ * Right now only Windows can provide CPFORMAT_FILECONTENTS data.
+ * Symlink file is not expected. Continue with next file if the
+ * type is not valid.
+ */
+ continue;
+ }
+
+ /* Update file time attributes. */
+ createTime = fileItem->validFlags & CP_FILE_VALID_CREATE_TIME ?
+ fileItem->createTime: -1;
+ accessTime = fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME ?
+ fileItem->accessTime: -1;
+ writeTime = fileItem->validFlags & CP_FILE_VALID_WRITE_TIME ?
+ fileItem->writeTime: -1;
+ attrChangeTime = fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME ?
+ fileItem->attrChangeTime: -1;
+
+ if (!File_SetTimes(filePathName.c_str(),
+ createTime,
+ accessTime,
+ writeTime,
+ attrChangeTime)) {
+ /* Not a critical error, only log it. */
+ Debug("%s: File_SetTimes failed with file [%s].\n",
+ __FUNCTION__, filePathName.c_str());
+ }
+
+ /* Update file permission attributes. */
+ if (fileItem->validFlags & CP_FILE_VALID_PERMS) {
+ if (Posix_Chmod(filePathName.c_str(),
+ fileItem->permissions) < 0) {
+ /* Not a critical error, only log it. */
+ Debug("%s: Posix_Chmod failed with file [%s].\n",
+ __FUNCTION__, filePathName.c_str());
+ }
+ }
+
+ /*
+ * If there is no DIRSEPC inside the fileName, this file/directory is a
+ * top level one. We only put top level name into uri list.
+ */
+ if (fileName.find(DIRSEPS, 0) == utf::string::npos) {
+ m_HGFileContentsUriList += "file://" + filePathName + "\r\n";
+ }
+ }
+ Debug("%s: created uri list [%s].\n",
+ __FUNCTION__, m_HGFileContentsUriList.c_str());
+ ret = true;
+
+exit:
+ xdr_free((xdrproc_t) xdr_CPFileContents, (char *)&fileContents);
+ if (tempDir && !ret) {
+ DnD_DeleteStagingFiles(tempDir, FALSE);
+ }
+ free(tempDir);
+ return ret;
+}
+
+
+/**
+ *
+ * Tell host that we are done with HG DnD initialization.
+ */
+
+void
+DnDUI::SourceDragStartDone(void)
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ m_inHGDrag = true;
+ m_DnD->HGDragStartDone();
+}
+
+
+/**
+ *
+ * Handler for when the guest provides drag status during a host->guest
+ * operation. This will change as we drag over different things in the guest.
+ * Here, we map what is report to a Gdk drag action, and then forward this
+ * status value to the Gdk drag context.
+ *
+ * @param[in] effect drop effect
+ * @param[in] gc Gdk drag context object, to which status is forwarded.
+ */
+
+void
+DnDUI::SourceFeedbackChangedCB(DND_DROPEFFECT effect,
+ const Glib::RefPtr<Gdk::DragContext> dc)
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ if (effect == DROP_NONE) {
+ m_GHDnDAction = (Gdk::DragAction)0;
+ } else if (effect & DROP_COPY) {
+ m_GHDnDAction = Gdk::ACTION_COPY;
+ } else if (effect & DROP_MOVE) {
+ m_GHDnDAction = Gdk::ACTION_MOVE;
+ } else if (effect & DROP_LINK) {
+ /*
+ * We don't do link.
+ */
+ m_GHDnDAction = Gdk::ACTION_COPY;
+ } else {
+ m_GHDnDAction = (Gdk::DragAction)0;
+ }
+ m_GHDnDHostStatus = !!effect;
+
+ dc->drag_status(m_GHDnDAction, GDK_CURRENT_TIME);
+}
+
+
+/**
+ *
+ * Cancel current HG DnD.
+ */
+
+void
+DnDUI::SourceCancelCB(void)
+{
+ Debug("%s: entering\n", __FUNCTION__);
+ m_inHGDrag = false;
+}
+
+
+/**
+ *
+ * Got drop from host side. Add block first then host can simulate the drop
+ * in the guest.
+ */
+
+void
+DnDUI::SourceDropCB(void)
+{
+ m_inHGDrag = false;
+
+ if (m_needsBlock) {
+ AddBlock();
+ m_needsBlock = false;
+ }
+}
+
+
+/**
+ *
+ * Callback when HG file transfer is done, which finishes the file
+ * copying from host to guest staging directory.
+ *
+ * @param[in] success if true, transfer was successful
+ * @param[in] path of staging dir (which will have a block that needs removing)
+ */
+
+void
+DnDUI::GetLocalFilesDoneCB(bool success,
+ std::vector<uint8> stagingDir)
+{
+ Debug("%s: %s\n", __FUNCTION__, success ? "success" : "failed");
+ /* Copied files are already removed in common layer. */
+ stagingDir.clear();
+ Reset();
+ m_HGGetDataInProgress = false;
+ RemoveBlock();
+}
+
+
+/* Target functions for GH DnD. */
+
+/**
+ *
+ * This is triggered when user drags valid data from guest to host. Try to
+ * get clip data and notify host to start GH DnD.
+ */
+
+void
+DnDUI::TargetDragEnter(void)
+{
+ Debug("%s: entering\n", __FUNCTION__);
+
+ /* Check if there is valid data with current detection window. */
+ if (!CPClipboard_IsEmpty(&m_clipboard)) {
+ Debug("%s: got valid data from detWnd.\n", __FUNCTION__);
+ m_DnD->DragEnter(&m_clipboard);
+ }
+}
+
+
+/**
+ *
+ * Shows/hides drag detection windows based on the mask.
+ *
+ * @param[in] bShow if true, show the window, else hide it.
+ * @param[in] x x-coordinate to which the detection window needs to be moved
+ * @param[in] y y-coordinate to which the detection window needs to be moved
+ */
+
+void
+DnDUI::UpdateDetWndCB(bool bShow,
+ int32 x,
+ int32 y)
+{
+ /* If the window is being shown, move it to the right place. */
+ if (bShow) {
+ x = MAX(x - DRAG_DET_WINDOW_WIDTH / 2, 0);
+ y = MAX(y - DRAG_DET_WINDOW_WIDTH / 2, 0);
+
+ m_detWnd->Show();
+ m_detWnd->Raise();
+ m_detWnd->SetGeometry(x, y, 2 * DRAG_DET_WINDOW_WIDTH, 2 * DRAG_DET_WINDOW_WIDTH);
+ /*
+ * Wiggle the mouse here. Especially for G->H DnD, this improves
+ * reliability of making the drag escape the guest window immensly.
+ * Stolen from the legacy V2 DnD code.
+ */
+
+ DnDHGFakeMove(x, y);
+ } else {
+ m_detWnd->Hide();
+ }
+}
+
+
+/**
+ *
+ * Shows/hides full-screen Unity drag detection window.
+ *
+ * @param[in] bShow if true, show the window, else hide it.
+ * @param[in] unityWndId active front window
+ */
+
+void
+DnDUI::UpdateUnityDetWndCB(bool bShow,
+ uint32 unityWndId)
+{
+ if (bShow && unityWndId > 0) {
+ int width = m_detWndFull->GetScreenWidth();
+ int height = m_detWndFull->GetScreenHeight();
+ m_detWndFull->SetGeometry(0, 0, width, height);
+ m_detWndFull->Lower();
+ m_detWndFull->Show();
+ } else {
+ m_detWndFull->Hide();
+ }
+}
+
+
+/**
+ *
+ * Reset the UI independent DnD layer.
+ */
+
+void
+DnDUI::Reset(void)
+{
+ Debug("%s: entering\n", __FUNCTION__);
+ if (m_DnD) {
+ m_DnD->ResetDnD();
+ }
+}
+
+
+/**
+ *
+ * "drag_motion" signal handler for GTK. We should respond by setting drag
+ * status. Note that there is no drag enter signal. We need to figure out
+ * if a new drag is happening on our own. Also, we don't respond with a
+ * "allowed" drag status right away, we start a new drag operation over VMDB
+ * (which tries to notify the host of the new operation). Once the host has
+ * responded), we respond with a proper drag status.
+ *
+ * @param[in] dc associated drag context
+ * @param[in] x x coordinate of the drag motion
+ * @param[in] y y coordinate of the drag motion
+ * @param[in] time time of the drag motion
+ *
+ * @return returning false means we won't get notified of future motion. So,
+ * we only return false if we don't recognize the types being offered. We
+ * return true otherwise, even if we don't accept the drag right now for some
+ * other reason.
+ */
+
+bool
+DnDUI::LocalDragMotionCB(const Glib::RefPtr<Gdk::DragContext> &dc,
+ int x,
+ int y,
+ guint time)
+{
+ DND_DROPEFFECT effect;
+
+ effect = ToDropEffect(dc->get_action());
+ if (effect != m_effect) {
+ m_effect = effect;
+ Debug("%s: Updating feedback\n", __FUNCTION__);
+ SourceUpdateFeedback(m_effect);
+ }
+
+ /*
+ * If this is a Host to Guest drag, we are done here, so return.
+ */
+
+ if (m_inHGDrag) {
+ return true;
+ }
+
+ Gdk::DragAction srcActions;
+ Gdk::DragAction suggestedAction;
+ Glib::ustring target = m_detWnd->drag_dest_find_target(dc);
+
+ if (!m_DnD->IsDnDAllowed()) {
+ Debug("%s: No dnd allowed!\n", __FUNCTION__);
+ m_GHDnDAction = (Gdk::DragAction)0;
+ dc->drag_status(m_GHDnDAction, time);
+ return true;
+ }
+
+ /* Check if dnd began from this vm. */
+
+ /*
+ * TODO: Once we upgrade to shipping gtkmm 2.12, we can go back to
+ * Gdk::DragContext::get_targets, but API/ABI broke between 2.10 and
+ * 2.12, so we work around it like this for now.
+ */
+ Glib::ListHandle<std::string, Gdk::AtomStringTraits> targets(
+ dc->gobj()->targets, Glib::OWNERSHIP_NONE);
+
+ std::list<Glib::ustring> as = targets;
+ std::list<Glib::ustring>::iterator result;
+ char *pid;
+ pid = Str_Asprintf(NULL, "guest-dnd-target %d", static_cast<int>(getpid()));
+ if (pid) {
+ result = std::find(as.begin(), as.end(), std::string(pid));
+ free(pid);
+ } else {
+ result = as.end();
+ }
+ if (result != as.end()) {
+ Debug("%s: found re-entrant drop target, pid %s\n", __FUNCTION__, pid );
+ if (m_GHDnDDataReceived) {
+ Debug("%s: re-entrant calling SetMouse()\n", __FUNCTION__);
+ m_DnD->SetMouse(x, y, true);
+ } else {
+ Debug("%s: re-entrant calling DragEnter()\n", __FUNCTION__);
+ m_localDragLeaveTimer.disconnect();
+ m_DnD->DragEnter(NULL);
+ m_GHDnDDataReceived = true;
+ m_VMIsSource = true;
+ }
+ return true;
+ }
+
+ if (target != "") {
+ /*
+ * We give preference to the suggested action from the source, and prefer
+ * copy over move.
+ */
+ suggestedAction = dc->get_suggested_action();
+ srcActions = dc->get_actions();
+ if (suggestedAction == Gdk::ACTION_COPY || suggestedAction == Gdk::ACTION_MOVE) {
+ m_GHDnDAction = suggestedAction;
+ } else if (srcActions & Gdk::ACTION_COPY) {
+ m_GHDnDAction= Gdk::ACTION_COPY;
+ } else if (srcActions & Gdk::ACTION_MOVE) {
+ m_GHDnDAction = Gdk::ACTION_MOVE;
+ } else {
+ m_GHDnDAction = (Gdk::DragAction)0;
+ }
+ } else {
+ m_GHDnDAction = (Gdk::DragAction)0;
+ }
+
+ if (m_GHDnDAction != (Gdk::DragAction)0) {
+ if (!m_GHDnDInProgress) {
+ Debug("%s: new drag, need to get data for host\n", __FUNCTION__);
+ /*
+ * This is a new drag operation. We need to start a drag thru the
+ * backdoor, and to the host. Before we can tell the host, we have to
+ * retrieve the drop data.
+ */
+ m_GHDnDInProgress = true;
+ m_GHDnDAction = (Gdk::DragAction)0;
+ /* only begin drag enter after we get the data */
+ /* Need to grab all of the data. */
+ m_detWnd->drag_get_data(dc, target, time);
+ } else if (m_GHDnDDataReceived) {
+ Debug("%s: m_GHDnDDataReceived, setting mouse position\n", __FUNCTION__);
+ m_DnD->SetMouse(x, y, true);
+
+ if (m_GHDnDHostStatus) {
+ /* Got host response, respond with a proper drag status. */
+ Debug("%s: Existing status, calling drag_status()\n", __FUNCTION__);
+ dc->drag_status(m_GHDnDAction, time);
+ }
+ } else {
+ Debug("%s: Multiple drag motions before gh data has been received.\n",
+ __FUNCTION__);
+ }
+ } else {
+ Debug("%s: Invalid drag\n", __FUNCTION__);
+ return false;
+ }
+ return true;
+}
+
+
+/**
+ *
+ * Got feedback from our DropSource, send it over to host. Called by
+ * drag motion callback.
+ *
+ * @param[in] effect feedback to send to the UI-independent DnD layer.
+ */
+
+void
+DnDUI::SourceUpdateFeedback(DND_DROPEFFECT effect)
+{
+ Debug("%s: entering\n", __FUNCTION__);
+ m_DnD->SetFeedback(effect);
+}
+
+
+/**
+ *
+ * "drag_leave" signal handler for GTK. We can't clean up the drop
+ * operation here, because it might be part of a drop. See the
+ * LocalDragLeaveTimeout() function for more details.
+ *
+ * @param[in] dc drag context
+ * @param[in] time time of the drag
+ */
+
+void
+DnDUI::LocalDragLeaveCB(const Glib::RefPtr<Gdk::DragContext> &dc, guint time)
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ m_localDragLeaveTimer.disconnect();
+ m_localDragLeaveTimer = Glib::signal_timeout().connect(
+ sigc::bind_return(sigc::mem_fun(this, &DnDUI::LocalDragLeaveTimeout), false),
+ DRAG_LEAVE_TIMEOUT);
+ m_feedbackChanged.disconnect();
+ dc->drag_finish(true, dc->get_action() == Gdk::ACTION_MOVE, time);
+}
+
+
+/**
+ *
+ * Gtk emits "drag_leave" both when the mouse leaves our widget (in which
+ * case we should cancel the in progress dnd operation), and as part
+ * of a "drag_drop" (in which case our drag_leave handler should NOT
+ * cancel the operation. The trouble is, our drag_leave handler does not
+ * have enough information to determine whether it's dealing with a
+ * real leave or a drop. So, the drag_leave handler sets a timeout which
+ * calls this function when it expires.
+ *
+ * If this function is called, it means a previous "drag_leave" signal is
+ * really a leave and we should clean up the in-progress drag operation.
+ *
+ * @note side effects: cancel the drop operation and tell the host to
+ * cancel its drop operation.
+ */
+
+void
+DnDUI::LocalDragLeaveTimeout(void)
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ m_DnD->DragLeave(0, 0);
+ ResetUIStateCB();
+}
+
+
+/**
+ *
+ * "drag_drop" signal handler for GTK. Send the drop to the host (by
+ * way of the backdoor), then tell the host to get the files.
+ *
+ * @param[in] dc drag context
+ * @param[in] x x location of the drop
+ * @param[in] y y location of the drop
+ * @param[in] time timestamp for the drop
+ *
+ * @return true on success, false otherwise.
+ */
+
+bool
+DnDUI::LocalDragDropCB(const Glib::RefPtr<Gdk::DragContext> &dc,
+ int x,
+ int y,
+ guint time)
+{
+ Debug("%s: enter x %d y %d\n", __FUNCTION__, x, y);
+
+ Glib::ustring target;
+
+ m_localDragLeaveTimer.disconnect();
+ target = m_detWnd->drag_dest_find_target(dc);
+
+ if (m_VMIsSource) {
+ Debug("%s: Dropping in same vm.\n", __FUNCTION__);
+ /* Act as a drop */
+ ResetUIStateCB();
+ return false;
+ }
+
+ if (target == "") {
+ Debug("%s: No valid data on clipboard.\n", __FUNCTION__);
+ m_DnD->ResetDnD();
+ return false;
+ }
+
+ if (CPClipboard_IsEmpty(&m_clipboard)) {
+ Debug("%s: No valid data on m_clipboard.\n", __FUNCTION__);
+ m_DnD->ResetDnD();
+ return false;
+ }
+ return true;
+}
+
+
+/**
+ *
+ * "drag_data_get" handler for GTK. We don't send drop until we are done.
+ *
+ * @param[in] dc drag state
+ * @param[in] selection_data buffer for data
+ * @param[in] info unused
+ * @param[in] time timestamp
+ *
+ * @note if the drop has occurred, the files are copied from the guest.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+DnDUI::LocalDragDataGetCB(const Glib::RefPtr<Gdk::DragContext> &dc,
+ Gtk::SelectionData& selection_data,
+ guint info,
+ guint time)
+{
+ size_t index = 0;
+ std::string str;
+ std::string uriList;
+ std::string stagingDirName;
+ void *buf;
+ size_t sz;
+ utf::utf8string hgData;
+ DnDFileList fList;
+ std::string pre;
+ std::string post;
+
+ const utf::string target = selection_data.get_target().c_str();
+
+ if (target == DRAG_TARGET_NAME_URI_LIST &&
+ CPClipboard_GetItem(&m_clipboard, CPFORMAT_FILELIST, &buf, &sz)) {
+
+ /* Provide path within vmblock file system instead of actual path. */
+ stagingDirName = GetLastDirName(m_HGStagingDir);
+ if (stagingDirName.length() == 0) {
+ Debug("%s: Cannot get staging directory name, stagingDir: %s\n",
+ __FUNCTION__, m_HGStagingDir.c_str());
+ return;
+ }
+
+ if (!fList.FromCPClipboard(buf, sz)) {
+ Debug("%s: Can't get data from clipboard\n", __FUNCTION__);
+ return;
+ }
+
+ /* Provide URIs for each path in the guest's file list. */
+ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
+ pre = FCP_GNOME_LIST_PRE;
+ post = FCP_GNOME_LIST_POST;
+ } else if (FCP_TARGET_INFO_URI_LIST == info) {
+ pre = DND_URI_LIST_PRE_KDE;
+ post = DND_URI_LIST_POST;
+ } else {
+ Debug("%s: Unknown request target: %s\n", __FUNCTION__,
+ selection_data.get_target().c_str());
+ return;
+ }
+
+ /* Provide path within vmblock file system instead of actual path. */
+ hgData = fList.GetRelPathsStr();
+
+ /* Provide URIs for each path in the guest's file list. */
+ while ((str = GetNextPath(hgData, index).c_str()).length() != 0) {
+ uriList += pre;
+ if (DnD_BlockIsReady(m_blockCtrl)) {
+ uriList += m_blockCtrl->blockRoot;
+ uriList += DIRSEPS + stagingDirName + DIRSEPS + str + post;
+ } else {
+ uriList += DIRSEPS + m_HGStagingDir + DIRSEPS + str + post;
+ }
+ }
+
+ m_HGGetDataInProgress = true;
+ selection_data.set(DRAG_TARGET_NAME_URI_LIST, uriList.c_str());
+ m_needsBlock = true;
+ m_isFileDnD = true;
+ return;
+ }
+
+ if (target == DRAG_TARGET_NAME_URI_LIST &&
+ CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILECONTENTS)) {
+ Debug("%s: Providing uriList [%s] for file contents DnD\n",
+ __FUNCTION__, m_HGFileContentsUriList.c_str());
+
+ selection_data.set(DRAG_TARGET_NAME_URI_LIST,
+ m_HGFileContentsUriList.c_str());
+ return;
+ }
+
+ if ((target == TARGET_NAME_STRING ||
+ target == TARGET_NAME_TEXT_PLAIN ||
+ target == TARGET_NAME_UTF8_STRING ||
+ target == TARGET_NAME_COMPOUND_TEXT) &&
+ CPClipboard_GetItem(&m_clipboard, CPFORMAT_TEXT, &buf, &sz)) {
+ Debug("%s: providing plain text, size %"FMTSZ"u\n", __FUNCTION__, sz);
+ selection_data.set(target.c_str(), (const char *)buf);
+ return;
+ }
+
+ if ((target == TARGET_NAME_APPLICATION_RTF ||
+ target == TARGET_NAME_TEXT_RICHTEXT) &&
+ CPClipboard_GetItem(&m_clipboard, CPFORMAT_RTF, &buf, &sz)) {
+ Debug("%s: providing rtf text, size %"FMTSZ"u\n", __FUNCTION__, sz);
+ selection_data.set(target.c_str(), (const char *)buf);
+ return;
+ }
+
+ /* Can not get any valid data, cancel this HG DnD. */
+ Debug("%s: no valid data for HG DnD\n", __FUNCTION__);
+ m_DnD->SourceCancel();
+ ResetUIStateCB();
+}
+
+
+/**
+ *
+ * "drag_end" handler for GTK.
+ *
+ * @param[in] dc drag state
+ */
+
+void
+DnDUI::LocalDragEndCB(const Glib::RefPtr<Gdk::DragContext> &dc)
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ if (!m_isFileDnD) {
+ Reset();
+ }
+}
+
+
+/**
+ *
+ * "drag_data_received" signal handler for GTK. We requested the drag
+ * data earlier from some drag source on the guest; this is the response.
+ *
+ * This is for G->H DnD.
+ *
+ * @param[in] dc drag context
+ * @param[in] x where the drop happened
+ * @param[in] y where the drop happened
+ * @param[in] sd the received data
+ * @param[in] info the info that has been registered with the target in the
+ * target list.
+ * @param[in] time the timestamp at which the data was received.
+ */
+
+void
+DnDUI::LocalDragDataReceivedCB(const Glib::RefPtr<Gdk::DragContext> &dc,
+ int x,
+ int y,
+ const Gtk::SelectionData& sd,
+ guint info,
+ guint time)
+{
+ Debug("%s: enter\n", __FUNCTION__);
+ /* The HG DnD may already finish before we got response. */
+ if (!m_GHDnDInProgress) {
+ Debug("%s: not valid\n", __FUNCTION__);
+ return;
+ }
+
+ CPClipboard_Clear(&m_clipboard);
+
+ /*
+ * Try to get data provided from the source. If we cannot get any data,
+ * there is no need to inform the guest of anything.
+ */
+ LocalGetSelection(sd);
+ if (CPClipboard_IsEmpty(&m_clipboard)) {
+ Debug("%s: Failed getting item.\n", __FUNCTION__);
+ return;
+ }
+
+ /*
+ * There are two points in the DnD process at which this is called, and both
+ * are in response to us calling drag_data_get(). The first occurs on the
+ * first "drag_motion" received and is used to start a drag; at that point
+ * we need to provide the file list to the guest so we request the data from
+ * the target. The second occurs when the "drag_drop" signal is received
+ * and we confirm this data with the target before starting the drop.
+ *
+ * Note that we prevent against sending multiple "dragStart"s or "drop"s for
+ * each DnD.
+ */
+ if (!m_GHDnDDataReceived) {
+ Debug("%s: Drag entering.\n", __FUNCTION__);
+ m_GHDnDDataReceived = true;
+ m_localDragLeaveTimer.disconnect();
+ TargetDragEnter();
+ m_feedbackChanged = m_DnD->updateFeedbackChanged.connect(
+ sigc::bind(sigc::mem_fun(this, &DnDUI::SourceFeedbackChangedCB), dc));
+ } else if (m_GHDnDDropOccurred) {
+ Debug("%s: Drag dropping.\n", __FUNCTION__);
+ m_DnD->TargetDrop(&m_clipboard, x, y);
+ dc->drag_finish(true, dc->get_action() == Gdk::ACTION_MOVE, time);
+ /*
+ * Can't use ResetUIStateCB because file transfer state should not be
+ * cleared.
+ */
+ m_GHDnDDataReceived = false;
+ m_GHDnDAction = (Gdk::DragAction)0;
+ m_GHDnDHostStatus = false;
+ m_GHDnDInProgress = false;
+ m_feedbackChanged.disconnect();
+ } else {
+ Debug("%s: neither m_GHDnDDropOccurred, nor !m_GHDnDDataReceived\n",
+ __FUNCTION__);
+ }
+}
+
+
+/**
+ *
+ * Try to construct cross-platform clipboard data from selection data.
+ *
+ * @param[in] sd Gtk selection data to convert to CP clipboard data
+ */
+
+void
+DnDUI::LocalGetSelection(const Gtk::SelectionData& sd) // IN
+{
+ char *newPath;
+ char *newRelPath;
+ size_t newPathLen;
+ size_t index = 0;
+ DnDFileList fileList;
+ DynBuf buf;
+ uint64 totalSize = 0;
+ int64 size;
+
+ const utf::string target = sd.get_target().c_str();
+
+ /* Try to get file list. */
+ if (target == DRAG_TARGET_NAME_URI_LIST) {
+ /*
+ * Turn the uri list into two \0 delimited lists. One for full paths and
+ * one for just the last path component.
+ */
+ utf::string source = sd.get_data_as_string().c_str();
+ Debug("%s: Got file list: [%s]\n", __FUNCTION__, source.c_str());
+ /*
+ * In gnome, before file list there may be a extra line indicating it
+ * is a copy or cut.
+ */
+ if (source.length() >= 5 && source.compare(0, 5, "copy\n") == 0) {
+ source = source.erase(0, 5);
+ }
+
+ if (source.length() >= 4 && source.compare(0, 4, "cut\n") == 0) {
+ source = source.erase(0, 4);
+ }
+
+ while (source.length() > 0 &&
+ (source[0] == '\n' || source[0] == '\r' || source[0] == ' ')) {
+ source = source.erase(0, 1);
+ }
+
+ while ((newPath = DnD_UriListGetNextFile(source.c_str(),
+ &index,
+ &newPathLen)) != NULL) {
+
+ /*
+ * Parse relative path.
+ */
+ newRelPath = Str_Strrchr(newPath, DIRSEPC) + 1; // Point to char after '/'
+
+ if ((size = File_GetSize(newPath)) >= 0) {
+ totalSize += size;
+ } else {
+ Debug("%s: unable to get file size for %s\n", __FUNCTION__, newPath);
+ }
+ Debug("%s: Adding newPath '%s' newRelPath '%s'\n", __FUNCTION__,
+ newPath, newRelPath);
+ fileList.AddFile(newPath, newRelPath);
+ free(newPath);
+ }
+
+ DynBuf_Init(&buf);
+ fileList.SetFileSize(totalSize);
+ if (fileList.ToCPClipboard(&buf, false)) {
+ CPClipboard_SetItem(&m_clipboard, CPFORMAT_FILELIST, DynBuf_Get(&buf),
+ DynBuf_GetSize(&buf));
+ }
+ DynBuf_Destroy(&buf);
+ return;
+ }
+
+ /* Try to get plain text. */
+ if (target == TARGET_NAME_STRING ||
+ target == TARGET_NAME_TEXT_PLAIN ||
+ target == TARGET_NAME_UTF8_STRING ||
+ target == TARGET_NAME_COMPOUND_TEXT) {
+ utf::string source = sd.get_data_as_string().c_str();
+ if (source.bytes() > 0 &&
+ source.bytes() < DNDMSG_MAX_ARGSZ &&
+ CPClipboard_SetItem(&m_clipboard, CPFORMAT_TEXT, source.c_str(),
+ source.bytes() + 1)) {
+ Debug("%s: Got text, size %"FMTSZ"u\n", __FUNCTION__, source.bytes());
+ } else {
+ Debug("%s: Failed to get text\n", __FUNCTION__);
+ }
+ return;
+ }
+
+ /* Try to get RTF string. */
+ if (target == TARGET_NAME_APPLICATION_RTF ||
+ target == TARGET_NAME_TEXT_RICHTEXT) {
+ utf::string source = sd.get_data_as_string().c_str();
+ if (source.bytes() > 0 &&
+ source.bytes() < DNDMSG_MAX_ARGSZ &&
+ CPClipboard_SetItem(&m_clipboard, CPFORMAT_RTF, source.c_str(),
+ source.bytes() + 1)) {
+ Debug("%s: Got RTF, size %"FMTSZ"u\n", __FUNCTION__, source.bytes());
+ } else {
+ Debug("%s: Failed to get text\n", __FUNCTION__ );
+ }
+ }
+}
+
+
+/**
+ *
+ * Try to get last directory name from a full path name.
+ *
+ * @param[in] str pathname to process
+ *
+ * @return last dir name in the full path name if sucess, empty str otherwise
+ */
+
+std::string
+DnDUI::GetLastDirName(const std::string &str)
+{
+ std::string ret;
+ size_t start;
+ size_t end;
+
+ end = str.size() - 1;
+ if (end >= 0 && DIRSEPC == str[end]) {
+ end--;
+ }
+
+ if (end <= 0 || str[0] != DIRSEPC) {
+ return "";
+ }
+
+ start = end;
+
+ while (str[start] != DIRSEPC) {
+ start--;
+ }
+
+ return str.substr(start + 1, end - start);
+}
+
+
+/**
+ *
+ * Provide a substring containing the next path from the provided
+ * NUL-delimited string starting at the provided index.
+ *
+ * @param[in] str NUL-delimited path list
+ * @param[in] index current index into string
+ *
+ * @return a string with the next path or "" if there are no more paths.
+ */
+
+utf::utf8string
+DnDUI::GetNextPath(utf::utf8string& str,
+ size_t& index)
+{
+ utf::utf8string ret;
+ size_t start;
+
+ if (index >= str.length()) {
+ return "";
+ }
+
+ for (start = index; str[index] != '\0' && index < str.length(); index++) {
+ /*
+ * Escape reserved characters according to RFC 1630. We'd use
+ * Escape_Do() if this wasn't a utf::string, but let's use the same table
+ * replacement approach.
+ */
+ static char const Dec2Hex[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ };
+
+ unsigned char ubyte = str[index];
+
+ if (ubyte == '#' || /* Fragment identifier delimiter */
+ ubyte == '?' || /* Query string delimiter */
+ ubyte == '*' || /* "Special significance within specific schemes" */
+ ubyte == '!' || /* "Special significance within specific schemes" */
+ ubyte == '%' || /* Escape character */
+ ubyte >= 0x80) { /* UTF-8 encoding bytes */
+ str.replace(index, 1, "%");
+ str.insert(index + 1, 1, Dec2Hex[ubyte >> 4]);
+ str.insert(index + 2, 1, Dec2Hex[ubyte & 0xF]);
+ index += 2;
+ }
+ }
+
+ ret = str.substr(start, index - start);
+ Debug("%s: nextpath: %s", __FUNCTION__, ret.c_str());
+ index++;
+ return ret;
+}
+
+
+/**
+ *
+ * Issue a fake mouse move event to the detection window. Code stolen from
+ * DnD V2 Linux guest implementation, where it was originally defined as a
+ * macro.
+ *
+ * @param[in] x x-coordinate of location to move mouse to.
+ * @param[in] y y-coordinate of location to move mouse to.
+ *
+ * @return true on success, false on failure.
+ */
+
+bool
+DnDUI::DnDHGFakeMove(const int x,
+ const int y)
+{
+ return DnDFakeXEvents(false, false, false, false, true, x, y);
+}
+
+
+/**
+ *
+ * Fake X mouse events and window movement for the provided Gtk widget.
+ *
+ * This function will optionally show the widget, move the provided widget
+ * to either the provided location or the current mouse position if no
+ * coordinates are provided, and cause a button press or release event.
+ *
+ * @param[in] showWidget whether to show Gtk widget
+ * @param[in] buttonEvent whether to send a button event
+ * @param[in] buttonPress whether to press or release mouse
+ * @param[in] moveWindow: whether to move our window too
+ * @param[in] coordsProvided whether coordinates provided
+ * @param[in] xCoord x coordinate
+ * @param[in] yCoord y coordinate
+ *
+ * @return true on success, false on failure.
+ */
+
+bool
+DnDUI::DnDFakeXEvents(const bool showWidget,
+ const bool buttonEvent,
+ const bool buttonPress,
+ const bool moveWindow,
+ const bool coordsProvided,
+ const int xCoord,
+ const int yCoord)
+{
+ GtkWidget *widget;
+ Window rootWnd;
+ bool ret;
+ Display *dndXDisplay;
+ Window dndXWindow;
+ int x;
+ int y;
+
+ x = xCoord;
+ y = yCoord;
+
+ Debug("%s: enter\n", __FUNCTION__);
+ widget = GetDetWndAsWidget(false);
+
+ if (!widget) {
+ Debug("%s: unable to get widget\n", __FUNCTION__);
+ return false;
+ }
+
+ dndXDisplay = GDK_WINDOW_XDISPLAY(widget->window);
+ dndXWindow = GDK_WINDOW_XWINDOW(widget->window);
+
+ /*
+ * Turn on X synchronization in order to ensure that our X events occur in
+ * the order called. In particular, we want the window movement to occur
+ * before the mouse movement so that the events we are coercing do in fact
+ * happen.
+ */
+ XSynchronize(dndXDisplay, True);
+
+ if (showWidget) {
+ Debug("%s: showing Gtk widget\n", __FUNCTION__);
+ gtk_widget_show(widget);
+ gdk_window_show(widget->window);
+ }
+
+ /* Get the current location of the mouse if coordinates weren't provided. */
+ if (!coordsProvided) {
+ Window rootReturn;
+ Window childReturn;
+ int rootXReturn;
+ int rootYReturn;
+ int winXReturn;
+ int winYReturn;
+ unsigned int maskReturn;
+
+ rootWnd = RootWindow(dndXDisplay, DefaultScreen(dndXDisplay));
+ ret = XQueryPointer(dndXDisplay, rootWnd, &rootReturn, &childReturn,
+ &rootXReturn, &rootYReturn, &winXReturn, &winYReturn,
+ &maskReturn);
+ if (ret == False) {
+ Warning("%s: XQueryPointer() returned False.\n", __FUNCTION__);
+ XSynchronize(dndXDisplay, False);
+ return false;
+ }
+
+ Debug("%s: mouse is at (%d, %d)\n", __FUNCTION__, rootXReturn, rootYReturn);
+
+ x = rootXReturn;
+ y = rootYReturn;
+ }
+
+ if (moveWindow) {
+ /*
+ * Make sure the window is at this point and at the top (raised). The
+ * window is resized to be a bit larger than we would like to increase
+ * the likelihood that mouse events are attributed to our window -- this
+ * is okay since the window is invisible and hidden on cancels and DnD
+ * finish.
+ */
+ XMoveResizeWindow(dndXDisplay, dndXWindow, x, y, 25, 25);
+ XRaiseWindow(dndXDisplay, dndXWindow);
+ }
+
+ /*
+ * Generate mouse movements over the window. The second one makes ungrabs
+ * happen more reliably on KDE, but isn't necessary on GNOME.
+ */
+ XTestFakeMotionEvent(dndXDisplay, -1, x, y, CurrentTime);
+ XTestFakeMotionEvent(dndXDisplay, -1, x + 1, y + 1, CurrentTime);
+
+ if (buttonEvent) {
+ Debug("%s: faking left mouse button %s\n", __FUNCTION__,
+ buttonPress ? "press" : "release");
+ XTestFakeButtonEvent(dndXDisplay, 1, buttonPress, CurrentTime);
+ }
+
+ XSynchronize(dndXDisplay, False);
+ return true;
+}
+
+
+/**
+ *
+ * Get the GtkWidget pointer for a DragDetWnd object. The X11 Unity
+ * implementation requires access to the drag detection window as
+ * a GtkWindow pointer, which it uses to show and hide the detection
+ * window. This function is also called by the code that issues fake
+ * X events to the detection window.
+ *
+ * @param[in] full true to get the GtkWindow for the full (unity)
+ * detection window, otherwise false.
+ *
+ * @return a pointer to the GtkWidget for the detection window, or NULL
+ * on failure.
+ */
+
+GtkWidget *
+DnDUI::GetDetWndAsWidget(const bool full)
+{
+ GtkInvisible *window;
+ GtkWidget *widget = NULL;
+ DragDetWnd *detWnd;
+
+ if (full) {
+ detWnd = m_detWndFull;
+ } else {
+ detWnd = m_detWnd;
+ }
+
+ if (!detWnd) {
+ return NULL;
+ }
+ window = detWnd->gobj();
+ if (window) {
+ widget = GTK_WIDGET(window);
+ }
+ return widget;
+}
+
+
+/**
+ *
+ * Add a block for the current H->G file transfer. Must be paired with a
+ * call to RemoveBlock() on finish or cancellation.
+ */
+
+void
+DnDUI::AddBlock()
+{
+ if (DnD_BlockIsReady(m_blockCtrl) && m_blockCtrl->AddBlock(m_blockCtrl->fd, m_HGStagingDir.c_str())) {
+ m_blockAdded = true;
+ Debug("%s: add block for %s.\n", __FUNCTION__, m_HGStagingDir.c_str());
+ } else {
+ m_blockAdded = false;
+ Debug("%s: unable to add block dir %s.\n", __FUNCTION__, m_HGStagingDir.c_str());
+ }
+}
+
+
+/**
+ *
+ * Remove block for the current H->G file transfer. Must be paired with a
+ * call to AddBlock(), but it will only attempt to remove block if one is
+ * currently in effect.
+ */
+
+void
+DnDUI::RemoveBlock()
+{
+ if (m_blockAdded && !m_HGGetDataInProgress) {
+ Debug("%s: removing block for %s\n", __FUNCTION__, m_HGStagingDir.c_str());
+ m_blockCtrl->RemoveBlock(m_blockCtrl->fd, m_HGStagingDir.c_str());
+ m_blockAdded = false;
+ }
+}
+
+
+/**
+ *
+ * Convert a Gdk::DragAction value to its corresponding DND_DROPEFFECT.
+ *
+ * @param[in] the Gdk::DragAction value to return.
+ *
+ * @return the corresponding DND_DROPEFFECT, with DROP_UNKNOWN returned
+ * if no mapping is supported.
+ *
+ * @note DROP_NONE is not mapped in this function.
+ */
+
+DND_DROPEFFECT
+DnDUI::ToDropEffect(Gdk::DragAction action)
+{
+ DND_DROPEFFECT effect;
+
+ switch(action) {
+ case Gdk::ACTION_COPY:
+ effect = DROP_COPY;
+ break;
+ case Gdk::ACTION_MOVE:
+ effect = DROP_MOVE;
+ break;
+ case Gdk::ACTION_LINK:
+ effect = DROP_LINK;
+ break;
+ case Gdk::ACTION_PRIVATE:
+ case Gdk::ACTION_DEFAULT:
+ case Gdk::ACTION_ASK:
+ default:
+ effect = DROP_UNKNOWN;
+ break;
+ }
+ return effect;
+}
+
+
+
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/**
+ * @file dndUI.h
+ *
+ * Implement the methods that allow DnD between host and guest for
+ * protocols V3 or greater.
+ *
+ */
+
+#ifndef DND_UI_H
+#define DND_UI_H
+
+#include "stringxx/string.hh"
+
+extern "C" {
+#include "debug.h"
+#include "dnd.h"
+#include "str.h"
+#include "util.h"
+#include "vmblock.h"
+#include "dndClipboard.h"
+#include "dynbuf.h"
+#include "../dnd/dndFileContentsUtil.h"
+#include "dynxdr.h"
+#include "cpNameUtil.h"
+#include "posix.h"
+}
+
+#include "dnd.hh"
+#include "dndFileList.hh"
+#include "dragDetWnd.h"
+
+struct DblLnkLst_Links;
+
+/**
+ * The DnDUI class implements the UI portion of DnD V3 and greater
+ * versions of the protocol.
+ */
+class DnDUI
+{
+public:
+ DnDUI(DblLnkLst_Links *eventQueue);
+ ~DnDUI();
+ void Init();
+ void VmxDnDVersionChanged(struct RpcIn *rpcIn,
+ uint32 version)
+ { ASSERT(m_DnD); m_DnD->VmxDnDVersionChanged(rpcIn, version); }
+ void SetDnDAllowed(bool isDnDAllowed)
+ { ASSERT(m_DnD); m_DnD->SetDnDAllowed(isDnDAllowed); }
+ void Reset(void);
+ void ResetUIStateCB();
+ void SetBlockControl(DnDBlockControl *blockCtrl);
+ void SetUnityMode(Bool mode)
+ {m_unityMode = mode;};
+ DragDetWnd *GetFullDetWnd() {return m_detWndFull;}
+ GtkWidget *GetDetWndAsWidget(const bool full);
+
+ /**
+ * Source functions for HG DnD
+ */
+ void SourceDragStartDone(void);
+ void SourceUpdateFeedback(DND_DROPEFFECT effect);
+
+ /**
+ * Target function for GH DnD.
+ */
+ void TargetDragEnter(void);
+
+ /**
+ * Callbacks. H->G
+ */
+
+ bool LocalDragMotionCB(const Glib::RefPtr<Gdk::DragContext> &dc, int x,
+ int y, guint time);
+ void LocalDragDataReceivedCB(const Glib::RefPtr<Gdk::DragContext> &dc,
+ int x, int y, const Gtk::SelectionData &sd,
+ guint info, guint time);
+ void LocalGetSelection(const Gtk::SelectionData& sd);
+ void LocalDragLeaveCB(const Glib::RefPtr<Gdk::DragContext> &dc, guint time);
+ void LocalDragLeaveTimeout(void);
+ bool LocalDragDropCB(const Glib::RefPtr<Gdk::DragContext> &dc, int x, int y,
+ guint time);
+
+ void SourceFeedbackChangedCB(DND_DROPEFFECT effect, const Glib::RefPtr<Gdk::DragContext> dc);
+
+ void LocalDragDataGetCB(
+ const Glib::RefPtr<Gdk::DragContext>& context,
+ Gtk::SelectionData& selection_data, guint info, guint time);
+ void LocalDragEndCB(
+ const Glib::RefPtr<Gdk::DragContext>& context);
+
+#if defined(DETWNDTEST)
+ void CreateTestUI();
+#endif
+private:
+
+ sigc::connection m_localDragLeaveTimer;
+
+ void AddBlock();
+ void RemoveBlock();
+
+ /**
+ * Source functions for HG DnD.
+ */
+ void RemoteDragStartCB(const CPClipboard *clip,
+ std::string stagingDir);
+ void SourceDropCB(void);
+ void SourceCancelCB(void);
+
+ /**
+ * Source functions for HG file transfer.
+ */
+ void GetLocalFilesDoneCB(bool success, std::vector<uint8> stagingDir);
+
+ /**
+ * Misc methods.
+ */
+ std::string GetLastDirName(const std::string &str);
+ utf::utf8string GetNextPath(utf::utf8string &str, size_t& index);
+ void UpdateDetWndCB(bool bShow, int32 x, int32 y);
+ void UpdateUnityDetWndCB(bool bShow, uint32 unityWndId);
+ DND_DROPEFFECT ToDropEffect(Gdk::DragAction action);
+ void SetTargetsAndCallbacks();
+ bool DnDFakeXEvents(const bool showWidget, const bool buttonEvent,
+ const bool buttonPress, const bool moveWindow,
+ const bool coordsProvided, const int xCoord, const int yCoord);
+ bool DnDHGFakeMove(const int x, const int y);
+ bool LocalPrepareFileContentsDrag();
+
+ DblLnkLst_Links *m_eventQueue;
+ DnD *m_DnD;
+ std::string m_HGStagingDir;
+ utf::string m_HGFileContentsUriList;
+ DragDetWnd *m_detWnd;
+ DragDetWnd *m_detWndFull;
+ CPClipboard m_clipboard;
+ DnDBlockControl *m_blockCtrl;
+ bool m_HGGetDataInProgress;
+ int m_HGEffect;
+ bool m_blockAdded;
+
+ /* State to determine if drag motion is is a drag enter. */
+ bool m_GHDnDInProgress;
+ /* Icon updates from the guest. */
+ bool m_GHDnDHostStatus;
+ /* Drop actions for host and guest respectively. */
+ Gdk::DragAction m_GHDnDAction;
+ /* Only update mouse when we have clipboard contents from the host. */
+ bool m_GHDnDDataReceived;
+ bool m_GHDnDDropOccurred;
+ bool m_VMIsSource;
+ sigc::connection m_feedbackChanged;
+ bool m_unityMode;
+ bool m_inHGDrag;
+ DND_DROPEFFECT m_effect;
+ bool m_needsBlock;
+ bool m_isFileDnD;
+};
+
+#endif // DND_UI_H
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/**
+ * @file dragDetWnd.cpp
+ *
+ * Detection window code for Linux/X11, based on Gtkmm. Includes unit test
+ * code.
+ */
+
+#include "dragDetWnd.h"
+
+/**
+ *
+ * Constructor.
+ */
+
+extern "C" {
+#include "debug.h"
+}
+
+#include "dndUI.h"
+#include <list>
+
+/**
+ *
+ * Constructor.
+ */
+
+DragDetWnd::DragDetWnd()
+{
+}
+
+
+/**
+ *
+ * Destructor.
+ */
+
+DragDetWnd::~DragDetWnd()
+{
+}
+
+
+/**
+ * Flush the X connection.
+ */
+
+void
+DragDetWnd::Flush()
+{
+ Glib::RefPtr<Gdk::Display> gdkdisplay = Gdk::Display::get_default();
+ if (gdkdisplay) {
+ gdkdisplay->sync();
+ gdkdisplay->flush();
+ }
+}
+
+
+/**
+ *
+ * Show the window.
+ */
+
+void
+DragDetWnd::Show(void)
+{
+ show();
+ Flush();
+}
+
+
+/**
+ *
+ * Hide the window.
+ */
+
+void
+DragDetWnd::Hide(void)
+{
+ hide();
+ Flush();
+}
+
+
+/**
+ *
+ * Raise the window.
+ */
+
+void
+DragDetWnd::Raise(void)
+{
+ Glib::RefPtr<Gdk::Window> gdkwin = get_window();
+ if (gdkwin) {
+ gdkwin->raise();
+ }
+ Flush();
+}
+
+
+/**
+ *
+ * Lower the window.
+ */
+
+void
+DragDetWnd::Lower(void)
+{
+ Glib::RefPtr<Gdk::Window> gdkwin = get_window();
+ if (gdkwin) {
+ gdkwin->lower();
+ }
+ Flush();
+}
+
+
+/**
+ *
+ * Get the width of the screen associated with this window.
+ *
+ * @return width of screen, in pixels.
+ */
+
+int
+DragDetWnd::GetScreenWidth(void)
+{
+ Glib::RefPtr<Gdk::Screen> gdkscreen = get_screen();
+ return gdkscreen->get_width();
+}
+
+
+/**
+ *
+ * Get the height of the screen associated with this window.
+ *
+ * @return height of screen, in pixels.
+ */
+
+int
+DragDetWnd::GetScreenHeight(void)
+{
+ Glib::RefPtr<Gdk::Screen> gdkscreen = get_screen();
+ return gdkscreen->get_height();
+}
+
+
+#if defined(DETWNDDEBUG)
+/**
+ *
+ * Set default window attributes appropriate for debugging detection windows.
+ *
+ * @note This only applies to instances of DragDetWnd that are derived from
+ * GTK::Window.
+ */
+
+void
+DragDetWnd::DebugSetAttributes(void)
+{
+ set_default_size(1, 1);
+ set_resizable(true);
+ set_decorated(false);
+ set_type_hint(Gdk::WINDOW_TYPE_HINT_DOCK);
+}
+#endif
+
+
+/**
+ *
+ * Set the geometry of the window.
+ *
+ * @param[in] x desired x-coordinate of the window.
+ * @param[in] y desired y-coordinate of the window.
+ * @param[in] width desired width of the window.
+ * @param[in] height desired height of the window.
+ */
+
+void
+DragDetWnd::SetGeometry(const int x,
+ const int y,
+ const int width,
+ const int height)
+{
+ Glib::RefPtr<Gdk::Window> gdkwin = get_window();
+
+ if (gdkwin) {
+ gdkwin->move_resize(x, y, width, height);
+ Flush();
+ }
+}
+
+
+/**
+ *
+ * Get the current geometry of the window.
+ *
+ * @param[out] x current x-coordinate of the window.
+ * @param[out] y current y-coordinate of the window.
+ * @param[out] width current width of the window.
+ * @param[out] height current height of the window.
+ *
+ * @note The current geometry may be inaccurate if retrieved too quickly
+ * after a change made by SetGeometry(). This is due to the realities of
+ * X and window managers. Some of this is mitigated by the use of flush()
+ * and sync() calls in SetGeometry(), but these are no guarantee.
+ */
+
+void
+DragDetWnd::GetGeometry(int &x, int &y, int &width, int &height)
+{
+ int dummy;
+
+ Glib::RefPtr<Gdk::Window> gdkwin = get_window();
+ if (gdkwin) {
+ gdkwin->get_geometry(x, y, width, height, dummy);
+#if defined(DETWNDTEST)
+ Flush();
+#endif
+ }
+}
+
+/*
+ * Code below here is for unit tests.
+ */
+
+#if defined(DETWNDTEST)
+
+/**
+ *
+ * Add a button to launch unit tests to the drag detection window.
+ */
+
+void
+DragDetWndTest::CreateTestUI()
+{
+ m_button.set_label("Start Unit Tests");
+ add(m_button);
+ m_button.signal_clicked().connect(sigc::mem_fun(*this, &DragDetWndTest::RunUnitTests));
+ m_button.show();
+}
+
+
+/**
+ *
+ * Run some unit tests, then exit. Requires a main program, refer to
+ * bora-vmsoft/toolbox/linux/vmwareuser/detWndTest/main.cpp for an
+ * example.
+ */
+
+void
+DragDetWndTest::RunUnitTests()
+{
+ DragDetWnd testWnd;
+ int testCount = 0;
+ int failCount = 0;
+
+#if defined(DETWNDDEBUG)
+ testWnd.SetAttributes();
+#endif
+ testWnd.Show();
+ int x, y, width, height;
+ testWnd.GetGeometry(x, y, width, height);
+ printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height);
+
+ for (int i = 10; i < 50; Gtk::Main::iteration(), i++) {
+ testCount++;
+ printf("Setting geometry to x %d y %d w %d h %d\n", i * 10, i * 10, i * 10, i * 10);
+ testWnd.SetGeometry(i * 10, i * 10, i * 10, i * 10);
+ sleep(1);
+ testWnd.GetGeometry(x, y, width, height);
+ printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height);
+ if (x != i * 10 || y != i * 10 || width != i * 10) {
+ printf("FAIL x or y not correct\n");
+ failCount++;
+ }
+ }
+
+ for (int i = 49; i > 0; Gtk::Main::iteration(), i--) {
+ testCount++;
+ printf("Setting geometry to x %d y %d w %d h %d\n", i * 10, i * 10, i * 10, i * 10);
+ testWnd.SetGeometry(i * 10, i * 10, i * 10, i * 10);
+ sleep(1);
+ testWnd.GetGeometry(x, y, width, height);
+ printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height);
+ if (x != i * 10 || y != i * 10 || width != i * 10) {
+ printf("FAIL width or height not correct\n");
+ failCount++;
+ }
+ }
+
+ testWnd.SetGeometry(500, 500, 300, 300);
+
+ for (int i = 0; i < 60; Gtk::Main::iteration(), i++) {
+ if (i % 2) {
+ printf("Hide\n");
+ testWnd.Hide();
+ } else {
+ printf("Show\n");
+ testWnd.Show();
+ testWnd.Raise();
+ }
+ sleep(1);
+ }
+
+ printf("Done fail count %d (%.2f%%)\n", failCount, 100.0 * failCount/testCount);
+ Gtk::Main::quit();
+}
+#endif
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/**
+ * @file dragDetWnd.h
+ *
+ * Header for the DragDetWnd class.
+ */
+
+#ifndef DRAG_DET_WND_H
+#define DRAG_DET_WND_H
+
+#include <gtkmm.h>
+
+#if !defined(DETWNDTEST)
+extern "C" {
+ #include "dnd.h"
+}
+#endif
+
+class DnDUI;
+
+class DragDetWnd : public Gtk::Invisible
+{
+public:
+ DragDetWnd();
+ virtual ~DragDetWnd();
+
+ void Show();
+ void Hide();
+ void Raise();
+ void Lower();
+ int GetScreenWidth();
+ int GetScreenHeight();
+ void SetGeometry(const int x, const int y,
+ const int width, const int height);
+ void GetGeometry(int &x, int &y, int &width, int &height);
+#if defined(DETWNDEBUG)
+ void SetAttributes();
+#endif
+private:
+ void Flush();
+};
+
+#if defined(DETWNDTEST)
+class DragDetWndTest : public Gtk::Window
+{
+public:
+ void CreateTestUI();
+private:
+ virtual void RunUnitTests();
+ Gtk::Button m_button;
+};
+
+#endif
+
+#endif // DRAG_DET_WND_H
static Bool QueryX11Lock(Display *dpy, Window w, Atom lockAtom);
static void ReloadSelf(void);
static void VMwareUserRegisterCopyPaste(bool reg);
+static void VMwareUserRegisterDnD(bool reg);
/*
Bool gCanUseVMwareCtrl;
Bool gCanUseVMwareCtrlTopologySet;
guint gTimeoutId;
-int gBlockFd = -1;
+DnDBlockControl gBlockCtrl = { -1 };
/*
* All signals that:
FoundryToolsDaemon_UnregisterOpenUrl();
gOpenUrlRegistered = FALSE;
}
- if (gDnDRegistered) {
- DnD_Unregister(gHGWnd, gGHWnd);
- gDnDRegistered = FALSE;
- }
CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance();
- if (p && p->IsRegistered()) {
- p->Unregister();
+ if (p) {
+ p->UnregisterDnD();
+ p->UnregisterCP();
}
RpcIn_Destruct(gRpcIn);
gRpcIn = NULL;
VMwareUserRpcInResetCB(RpcInData *data) // IN/OUT
{
Debug("----------toolbox: Received 'reset' from vmware\n");
- if (gDnDRegistered) {
- DnD_OnReset(gHGWnd, gGHWnd);
- }
CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance();
if (p) {
p->OnReset();
} else {
FoundryToolsDaemon_RegisterOpenUrlCapability();
}
- if (!gDnDRegistered) {
- gDnDRegistered = DnD_Register(gHGWnd, gGHWnd);
- if (gDnDRegistered) {
- UnityDnD state;
- state.detWnd = gGHWnd;
- state.setMode = DnD_SetMode;
- Unity_SetActiveDnDDetWnd(&state);
- }
- } else if (DnD_GetVmxDnDVersion() > 1) {
- if (!DnD_RegisterCapability()) {
- DnD_Unregister(gHGWnd, gGHWnd);
- gDnDRegistered = FALSE;
- }
- }
+ VMwareUserRegisterDnD(TRUE);
VMwareUserRegisterCopyPaste(TRUE);
if (!HgfsServerManager_CapReg(TOOLS_DND_NAME, gHgfsServerRegistered)) {
* VMwareUserRegisterCopyPaste
*
* Call the CopyPasteDnDWrapper singleton to register, or unregister,
- * copy and paste with the host. The wrapper class will try whatever
- * versions are supported, in highest to lowest order when registering.
+ * copy and paste with the host. The wrapper class will try
+ * whatever versions are supported, in highest to lowest order when
+ * registering.
*
* Results:
* None.
if (p) {
p->SetUserData(static_cast<void *>(gUserMainWidget));
if (reg) {
- p->Register();
+ p->RegisterCP();
} else {
- p->Unregister();
+ p->UnregisterCP();
+ }
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMwareUserRegisterDnD
+ *
+ * Call the CopyPasteDnDWrapper singleton to register, or unregister,
+ * drag and drop with the host. The wrapper class will try
+ * whatever versions are supported, in highest to lowest order when
+ * registering.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Drag and drop capabilities will be (un)registered.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+VMwareUserRegisterDnD(bool reg) // IN: if TRUE, register, else unregister
+{
+ CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance();
+ if (p) {
+ p->SetUserData(static_cast<void *>(gUserMainWidget));
+ p->SetEventQueue(gEventQueue);
+ if (reg) {
+ p->RegisterDnD();
+ } else {
+ p->UnregisterDnD();
}
}
}
int index;
GuestApp_Dict *confDict;
const char *pathName;
+ int blockFd = -1;
#ifdef USE_NOTIFY
Bool notifyPresent = TRUE;
#endif
+ Bool usingBlock;
gOpenUrlRegistered = FALSE;
gDnDRegistered = FALSE;
gHgfsServerRegistered = FALSE;
- gBlockFd = -1;
gReloadSelf = FALSE;
gYieldBlock = FALSE;
gSigExit = FALSE;
* blocking driver if it is not root. If guestd autostarts vmware-user,
* guestd will first initialize it and pass block fd in with -blockFd.
*/
- if (index + 1 == argc) {
+ if (++index >= argc) {
Warning("The \""OPTION_BLOCK_FD"\" option on the command line requires an "
"argument.\n");
}
- index++;
- if (!StrUtil_StrToInt(&gBlockFd, argv[index])) {
+ if (!StrUtil_StrToInt(&blockFd, argv[index])) {
Warning("The \""OPTION_BLOCK_FD"\" option on the command line requires a "
"valid integer.\n");
- gBlockFd = -1;
+ blockFd = -1;
}
- Debug("vmware-user got blockFd = %d\n", gBlockFd);
+ Debug("vmware-user got blockFd = %d\n", blockFd);
} else {
Warning("Invalid \"%s\" option on the command line.\n", argv[index]);
}
}
}
+ /*
+ * vmware-user runs as current active account, and can not initialize blocking
+ * driver if it is not root. If guestd autostarts vmware-user, guestd will first
+ * initialize it and pass block fd in. If manually run vmware-user, here will
+ * try to initialize the blocking driver.
+ */
+ usingBlock = blockFd >= 0 ?
+ DnD_CompleteBlockInitialization(blockFd, &gBlockCtrl) :
+ DnD_InitializeBlocking(&gBlockCtrl);
+
+ if (!usingBlock) {
+ Debug("%s: vmware-user failed to initialize blocking driver.\n",
+ __FUNCTION__);
+ }
+
if (Signal_SetGroupHandler(gSignals, olds, ARRAYSIZE(gSignals),
VMwareUserSignalHandler) == 0 ) {
Panic("vmware-user can't set signal handler\n");
Debug_EnableToFile(NULL, FALSE);
}
- /*
- * vmware-user runs as current active account, and can not initialize blocking
- * driver if it is not root. If guestd autostarts vmware-user, guestd will first
- * initialize it and pass block fd in. If manually run vmware-user, here will
- * try to initialize the blocking driver.
- */
-
- if (gBlockFd < 0) {
- gBlockFd = DnD_InitializeBlocking();
- if (gBlockFd < 0) {
- Debug("%s: vmware-user failed to initialize blocking driver.\n",
- __FUNCTION__);
- }
- }
-
gUserMainWidget = VMwareUser_CreateWindow();
- CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance();
- if (p) {
- p->SetUserData(static_cast<void *>(gUserMainWidget));
- p->SetBlockFd(gBlockFd);
- }
-
gHGWnd = VMwareUser_CreateWindow();
gGHWnd = VMwareUser_CreateWindow();
/*
return EXIT_FAILURE;
}
+ CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance();
+ if (p) {
+ p->SetUserData(static_cast<void *>(gUserMainWidget));
+ p->SetBlockControl(&gBlockCtrl);
+ p->SetEventQueue(gEventQueue);
+ p->SetHGWnd(gHGWnd);
+ p->SetGHWnd(gGHWnd);
+ }
+
if (runningInForeignVM) {
Bool success = ForeignTools_Initialize(confDict, gEventQueue);
if (!success) {
break;
}
- /* XXX Refactor this. */
if (gYieldBlock) {
- Debug("Yielding vmblock descriptor.\n");
- if (gDnDRegistered) {
- DnD_Unregister(gHGWnd, gGHWnd);
- gDnDRegistered = FALSE;
- }
CopyPasteDnDWrapper *p = CopyPasteDnDWrapper::GetInstance();
if (p) {
- p->Unregister();
+ p->UnregisterDnD();
+ p->UnregisterCP();
}
- if (gBlockFd >= 0 && !DnD_UninitializeBlocking(gBlockFd)) {
+
+ if (DnD_BlockIsReady(&gBlockCtrl) &&
+ !DnD_UninitializeBlocking(&gBlockCtrl)) {
Debug("vmware-user failed to uninitialize blocking.\n");
}
- gBlockFd = -1;
gYieldBlock = FALSE;
}
}
Signal_ResetGroupHandler(gSignals, olds, ARRAYSIZE(gSignals));
- if (gBlockFd >= 0 && !DnD_UninitializeBlocking(gBlockFd)) {
+ if (DnD_BlockIsReady(&gBlockCtrl) &&
+ !DnD_UninitializeBlocking(&gBlockCtrl)) {
Debug("vmware-user failed to uninitialize blocking.\n");
}
#include "vm_basic_types.h"
#include "rpcout.h"
#include "rpcin.h"
+#include "dnd.h"
#include "guestApp.h"
extern Window gXRoot;
extern DblLnkLst_Links *gEventQueue;
extern GtkWidget *gUserMainWidget;
-extern int gBlockFd;
+extern DnDBlockControl gBlockCtrl;
#endif // _VMWAREUSER_INT_H_