vmmemctl-only/ 0000755 0000000 0000000 00000000000 12025726767 012375 5 ustar root root vmmemctl-only/autoconf/ 0000755 0000000 0000000 00000000000 12025726765 014211 5 ustar root root vmmemctl-only/autoconf/geninclude.c 0000444 0000000 0000000 00000002264 12025726766 016475 0 ustar root root /*********************************************************
* 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
#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
vmmemctl-only/autoconf/epoll.c 0000444 0000000 0000000 00000002355 12025726766 015474 0 ustar root root /*********************************************************
* 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
#include
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
#include
void poll_test(void) {
struct poll_wqueues test;
return poll_initwait(&test);
}
#endif
vmmemctl-only/autoconf/setnice.c 0000444 0000000 0000000 00000002163 12025726766 016010 0 ustar root root /*********************************************************
* 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
#include
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 21)
#include
void test(void) {
set_user_nice(current, -20);
}
#endif
vmmemctl-only/balloon_def.h 0000444 0000000 0000000 00000004605 12025726766 015014 0 ustar root root /*********************************************************
* Copyright (C) 2000 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
*
*********************************************************/
/*
* 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 */
vmmemctl-only/includeCheck.h 0000444 0000000 0000000 00000010246 12025726766 015127 0 ustar root root /*********************************************************
* 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
vmmemctl-only/vm_assert.h 0000444 0000000 0000000 00000024220 12025726766 014546 0 ustar root root /*********************************************************
* 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
#ifdef __cplusplus
#define ASSERT_IFNOT(cond, panic) (UNLIKELY(!(cond)) ? (panic) : (void)0)
#else
#define ASSERT_IFNOT(cond, panic) (UNLIKELY(!(cond)) ? (panic) : 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_ */
vmmemctl-only/vm_basic_defs.h 0000444 0000000 0000000 00000031565 12025726766 015341 0 ustar root root /*********************************************************
* 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.
#if defined _WIN32 && defined USERLEVEL
#include /*
* We re-define offsetof macro from stddef, make
* sure that its already defined before we do it
*/
#include // for Sleep() and LOWORD() etc.
#endif
/*
* Simple macros
*/
#if defined __APPLE__ && !defined KERNEL
# include
#else
// XXX the __cplusplus 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 __cplusplus
#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
#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 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) || defined(__FreeBSD__)
/* We do not have YIELD() as we do not need it yet... */
#elif defined(_WIN32)
# define YIELD() Sleep(0)
#else
# include // For sched_yield. Don't ask. --Jeremy.
# define YIELD() sched_yield()
#endif
/*
* Standardize some Posix names on Windows.
*/
#ifdef _WIN32 // {
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strtok_r strtok_s
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
#endif // ifndef _VM_BASIC_DEFS_H_
vmmemctl-only/vm_basic_types.h 0000444 0000000 0000000 00000056242 12025726766 015563 0 ustar root root /*********************************************************
* 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
typedef unsigned __int64 uint64;
typedef signed __int64 int64;
#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'
#if !defined VMX86_DEVEL // XXX until we clean up all the code -- edward
#pragma warning (disable :4133) // incompatible types - from 'struct VM *' to 'int *'
#pragma warning (disable :4047) // differs in levels of indirection
#endif
#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
#pragma warning (disable :4142) // benign redefinition of type
#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
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef int int32;
typedef short int16;
typedef char int8;
/*
* 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
#endif
#ifdef HAVE_SYS_TYPES_H
#include
#endif
#ifdef HAVE_SYS_INTTYPES_H
#include
#endif
#ifdef HAVE_STDINT_H
#include
#endif
#ifdef HAVE_STDLIB_H
#include
#endif
#if !defined(USING_AUTOCONF)
# if defined(__FreeBSD__) || defined(sun)
# ifdef KLD_MODULE
# include
# else
# if (BSD_VERSION >= 50)
# include
# include
# else
# include
# endif
# endif
# elif defined __APPLE__
# if KERNEL
# include
# include /* mostly for size_t */
# include
# else
# include
# include
# include
# include
# 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 __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/Darwin, Linux */
#define FMTSZ "z"
#define FMTPD "t"
#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(__APPLE__) || 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 __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)0)
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)0)
/* 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 UserVA32 UserVAConst; /* Userspace ptr to data that we may only read. */
typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */
#ifdef VMKERNEL
typedef UserVA32 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
#define EXTERN extern
#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 sun the uid_t is a ulong, but on
* Linux it's an int.
* Use this like this: printf("The uid is %"FMTUID".\n", uid);
*/
#ifdef sun
# 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_ */
vmmemctl-only/backdoor_def.h 0000444 0000000 0000000 00000013753 12025726766 015156 0 ustar root root /*********************************************************
* 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 */
/* BDOOR_CMD_GETOS2INTCURSOR, 22, is very old and defunct. Reuse. */
#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 */
/* BDOOR_CMD_INITLSIOPROM, 36, was merged with 28. Reuse. */
#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
/* BDOOR_CMD_OSNOTMACOSXSERVER, not crossported to this branch yet. */
#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_MAX 59
/*
* 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
vmmemctl-only/backdoor_types.h 0000444 0000000 0000000 00000006727 12025726766 015567 0 ustar root root /*********************************************************
* 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_ */
vmmemctl-only/compat_completion.h 0000444 0000000 0000000 00000013710 12025726766 016261 0 ustar root root /*********************************************************
* 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
#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
#include "compat_sched.h"
#include "compat_list.h"
#include // 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__ */
vmmemctl-only/compat_file.h 0000444 0000000 0000000 00000003523 12025726766 015030 0 ustar root root /*********************************************************
* 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__ */
vmmemctl-only/compat_kernel.h 0000444 0000000 0000000 00000005143 12025726766 015371 0 ustar root root /*********************************************************
* 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
#include
/*
* 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__ */
vmmemctl-only/compat_list.h 0000444 0000000 0000000 00000003575 12025726766 015073 0 ustar root root /*********************************************************
* 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
/*
* 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__ */
vmmemctl-only/compat_mm.h 0000444 0000000 0000000 00000010207 12025726766 014517 0 ustar root root /*********************************************************
* 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
/* 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__ */
vmmemctl-only/compat_module.h 0000444 0000000 0000000 00000004372 12025726766 015401 0 ustar root root /*********************************************************
* 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
/*
* 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__ */
vmmemctl-only/compat_page.h 0000444 0000000 0000000 00000004663 12025726766 015033 0 ustar root root /*********************************************************
* 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
#include
/* 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 in 2.2.18, and was moved to
* 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 and
* , 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__ */
vmmemctl-only/compat_sched.h 0000444 0000000 0000000 00000024252 12025726766 015201 0 ustar root root /*********************************************************
* 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
/* 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
# include
/*
* 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
#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
#include
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
/*
* 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__ */
vmmemctl-only/compat_semaphore.h 0000444 0000000 0000000 00000003142 12025726766 016071 0 ustar root root /*********************************************************
* 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
#else
# include
#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__ */
vmmemctl-only/compat_spinlock.h 0000444 0000000 0000000 00000004606 12025726766 015736 0 ustar root root /*********************************************************
* 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
#else
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30)
# include
# 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__ */
vmmemctl-only/compat_version.h 0000444 0000000 0000000 00000006165 12025726766 015603 0 ustar root root /*********************************************************
* 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
/* 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__ */
vmmemctl-only/compat_wait.h 0000444 0000000 0000000 00000015642 12025726767 015063 0 ustar root root /*********************************************************
* 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
#include
#include
#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__ */
vmmemctl-only/driver-config.h 0000444 0000000 0000000 00000004250 12025726767 015303 0 ustar root root /*********************************************************
* 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
#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
# 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
# define _STDINT_H 1
#endif
#ifndef __KERNEL__
# define __KERNEL__
#endif
#endif
vmmemctl-only/backdoorGcc32.c 0000444 0000000 0000000 00000014036 12025726767 015111 0 ustar root root /*********************************************************
* 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
*
*********************************************************/
/*
* 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
vmmemctl-only/backdoorGcc64.c 0000444 0000000 0000000 00000012656 12025726767 015124 0 ustar root root /*********************************************************
* 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
*
*********************************************************/
/*
* 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
vmmemctl-only/backdoorInt.h 0000444 0000000 0000000 00000002010 12025726767 014774 0 ustar root root /*********************************************************
* 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);
vmmemctl-only/backdoor.h 0000444 0000000 0000000 00000002471 12025726767 014334 0 ustar root root /*********************************************************
* 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_ */
vmmemctl-only/os.h 0000444 0000000 0000000 00000004611 12025726767 013167 0 ustar root root /*********************************************************
* Copyright (C) 2000 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
*
*********************************************************/
/*
* 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 */
vmmemctl-only/vmballoon.c 0000444 0000000 0000000 00000112022 12025726767 014526 0 ustar root root /*********************************************************
* Copyright (C) 2000 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
*
*********************************************************/
/*
* 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
vmmemctl-only/vmballoon.h 0000444 0000000 0000000 00000004000 12025726767 014527 0 ustar root root /*********************************************************
* Copyright (C) 2000 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
*
*********************************************************/
/*
* 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 */
vmmemctl-only/backdoor_balloon.h 0000444 0000000 0000000 00000002472 12025726767 016043 0 ustar root root /*********************************************************
* 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
*
*********************************************************/
/*
* 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_ */
vmmemctl-only/os.c 0000444 0000000 0000000 00000036673 12025726767 013177 0 ustar root root /*********************************************************
* Copyright (C) 2000 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
*
*********************************************************/
/*
* os.c --
*
* Wrappers for Linux system functions required by "vmmemctl".
* This allows customers to build their own vmmemctl driver for
* custom versioned kernels without the need for source code.
*/
/*
* Compile-Time Options
*/
#define OS_DISABLE_UNLOAD (0)
#define OS_DEBUG (1)
/*
* Includes
*/
#include "driver-config.h"
#include "compat_module.h"
#include
#include "compat_kernel.h"
#include "compat_completion.h"
#include "compat_mm.h"
#include
#include
#include
#include "compat_sched.h"
#include
#include "compat_page.h"
#include "compat_wait.h"
#include "vmmemctl_version.h"
#ifdef CONFIG_PROC_FS
#include
#include
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
/*
* The get_info callback of proc_dir_entry was removed in 2.6.26.
* We must therefore use the seq_file interface from that point on.
*/
#define VMW_USE_SEQ_FILE
#include
#endif
#endif /* CONFIG_PROC_FS */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
#include
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)
int errno; /* compat_exit() needs global errno variable. */
#endif
/*
* Compatibility definitions.
*/
/*
* Execute as a separate kernel thread on 2.4.x kernels.
* Allow allocations from high memory on 2.4.x kernels.
*/
#define OS_KTHREAD (1)
#endif
#include "os.h"
/*
* Constants
*/
#ifdef OS_KTHREAD
/*
* Use __GFP_HIGHMEM to allow pages from HIGHMEM zone. We don't
* allow wait (__GFP_WAIT) for NOSLEEP page allocations. Use
* __GFP_NOWARN, if available, to suppress page allocation failure
* warnings.
*/
#ifdef __GFP_NOWARN
#define OS_PAGE_ALLOC_NOSLEEP (__GFP_HIGHMEM|__GFP_NOWARN)
#else
#define OS_PAGE_ALLOC_NOSLEEP (__GFP_HIGHMEM)
#endif
/*
* GFP_ATOMIC allocations dig deep for free pages. Maybe it is
* okay because balloon driver uses os_kmalloc_*() to only allocate
* few bytes, and the allocation requires a new page only occasionally.
* Still if __GFP_NOMEMALLOC flag is available, then use it to inform
* the guest's page allocator not to use emergency pools,
*/
#ifdef __GFP_NOWARN
#ifdef __GFP_NOMEMALLOC
#define OS_KMALLOC_NOSLEEP (GFP_ATOMIC|__GFP_NOMEMALLOC|__GFP_NOWARN)
#else
#define OS_KMALLOC_NOSLEEP (GFP_ATOMIC|__GFP_NOWARN)
#endif
#else
#ifdef __GFP_NOMEMALLOC
#define OS_KMALLOC_NOSLEEP (GFP_ATOMIC|__GFP_NOMEMALLOC)
#else
#define OS_KMALLOC_NOSLEEP (GFP_ATOMIC)
#endif
#endif
/*
* Use GFP_HIGHUSER when executing in a separate kernel thread
* context and allocation can sleep. This is less stressful to
* the guest memory system, since it allows the thread to block
* while memory is reclaimed, and won't take pages from emergency
* low-memory pools.
*/
#define OS_PAGE_ALLOC_CANSLEEP (GFP_HIGHUSER)
#else /* OS_KTHREAD not defined */
/* 2.2.x kernel is a special case. The balloon driver is unable
* to block (sleep) because it is not executing in a separate kernel
* thread. Therefore, the driver can only use NOSLEEP page
* allocations.
*
* Use __GFP_LOW when available (2.2.x kernels) to avoid stressing
* the guest memory system, otherwise simply use GFP_ATOMIC, which
* is always defined (normally as __GFP_HIGH).
*/
#ifdef __GFP_LOW
#define OS_PAGE_ALLOC_NOSLEEP (__GFP_LOW)
#define OS_KMALLOC_NOSLEEP (GFP_ATOMIC)
#else
#define OS_PAGE_ALLOC_NOSLEEP (GFP_ATOMIC)
#define OS_KMALLOC_NOSLEEP (GFP_ATOMIC)
#endif
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
#define OS_USE_SCHEDULE_DELAYED_WORK
#else
#undef OS_USE_SCHEDULE_DELAYED_WORK
#endif
/*
* Types
*/
typedef struct {
/* registered state */
os_timer_handler handler;
void *data;
int period;
/* termination flag */
volatile int stop;
/* system structures */
#ifdef OS_KTHREAD
wait_queue_head_t delay;
compat_completion notifyStart;
compat_completion notifyStop;
pid_t pid;
#else
#ifdef OS_USE_SCHEDULE_DELAYED_WORK
struct work_struct work;
#else
struct timer_list timer;
struct tq_struct task;
#endif
#endif
} os_timer;
typedef struct {
/* registered state */
os_status_handler handler;
const char *name_verbose;
const char *name;
} os_status;
typedef struct {
os_status status;
os_timer timer;
unsigned int totalMemoryPages;
} os_state;
/*
* Globals
*/
#ifdef CONFIG_PROC_FS
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
static struct proc_dir_entry *global_proc_entry;
#ifdef VMW_USE_SEQ_FILE
static int os_proc_open(struct inode *, struct file *);
static struct file_operations global_proc_fops = {
.open = os_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#else
static int os_proc_read(char *, char **, off_t, int);
#endif /* VMW_USE_SEQ_FILE */
#else
static int os_proc_read(char *, char **, off_t, int, int);
static struct proc_dir_entry global_proc_entry = {
0, 8, "vmmemctl", S_IFREG | S_IRUGO, 1, 0, 0, 0, NULL, os_proc_read,
};
#endif
#endif /* CONFIG_PROC_FS */
static os_state global_state;
/*
* Simple Wrappers
*/
void * CDECL
os_kmalloc_nosleep(unsigned int size)
{
return(kmalloc(size, OS_KMALLOC_NOSLEEP));
}
void CDECL
os_kfree(void *obj, unsigned int size)
{
kfree(obj);
}
void CDECL
os_bzero(void *s, unsigned int n)
{
memset(s, 0, n);
}
void CDECL
os_memcpy(void *dest, const void *src, unsigned int size)
{
memcpy(dest, src, size);
}
int CDECL
os_sprintf(char *str, const char *format, ...)
{
int result;
va_list args;
va_start(args, format);
result = vsprintf(str, format, args);
va_end(args);
return(result);
}
/*
* System-Dependent Operations
*/
char * CDECL
os_identity(void)
{
return("linux");
}
/*
* Predict the maximum achievable balloon size.
*
* In 2.4.x and 2.6.x kernels, the balloon driver can guess the number of pages
* that can be ballooned. But, for now let us just pass the totalram-size as the
* maximum achievable balloon size. Note that normally (unless guest kernel is
* booted with a mem=XX parameter) the totalram-size is equal to alloc.max.
*
* Returns the maximum achievable balloon size in pages
*/
unsigned int CDECL
os_predict_max_balloon_pages(void)
{
struct sysinfo info;
os_state *state = &global_state;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
/*
* In 2.4.0 and later, si_meminfo() is cheap. Moreover, we want to provide
* dynamic max balloon size later. So let us call si_meminfo() every
* iteration.
*/
si_meminfo(&info);
/* In 2.4.x and later kernels, info.totalram is in pages */
state->totalMemoryPages = info.totalram;
return(state->totalMemoryPages);
#else
/* 2.2.x kernel */
if (!state->totalMemoryPages) {
si_meminfo(&info); /* In 2.2.x, si_meminfo() is a costly operation */
/* In 2.2.x kernels, info.totalram is in bytes */
state->totalMemoryPages = info.totalram >> PAGE_SHIFT;
}
return(state->totalMemoryPages);
#endif
}
/*
* Use newer alloc_page() interface on 2.4.x kernels.
* Use "struct page *" value as page handle for clients.
*/
unsigned long CDECL
os_addr_to_ppn(unsigned long addr)
{
struct page *page = (struct page *) addr;
return(page_to_pfn(page));
}
unsigned long CDECL
os_alloc_reserved_page(int can_sleep)
{
struct page *page;
/* allocate page */
if (can_sleep) {
#ifdef OS_KTHREAD
page = alloc_page(OS_PAGE_ALLOC_CANSLEEP);
#else
return 0;
#endif
} else {
page = alloc_page(OS_PAGE_ALLOC_NOSLEEP);
}
return((unsigned long) page);
}
void CDECL
os_free_reserved_page(unsigned long addr)
{
/* deallocate page */
struct page *page = (struct page *) addr;
__free_page(page);
}
#ifndef OS_KTHREAD
static void os_timer_add(os_timer *t);
static void os_timer_bh(void *data)
{
os_timer *t = (os_timer *) data;
if (!t->stop) {
/* execute registered handler, rearm timer */
(*(t->handler))(t->data);
os_timer_add(t);
}
}
#ifndef OS_USE_SCHEDULE_DELAYED_WORK
static void os_timer_internal(ulong data)
{
os_timer *t = (os_timer *) data;
/* perform real work in registered bottom-half handler */
queue_task(&t->task, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
#endif
static void os_timer_add(os_timer *t)
{
#ifdef OS_USE_SCHEDULE_DELAYED_WORK
schedule_delayed_work(&t->work, t->period);
#else
/* schedule timer callback */
struct timer_list *timer = &t->timer;
timer->expires = jiffies + t->period;
add_timer(timer);
#endif
}
static void os_timer_remove(os_timer *t)
{
#ifdef OS_USE_SCHEDULE_DELAYED_WORK
cancel_delayed_work(&t->work);
flush_scheduled_work();
#else
/* deschedule timer callback */
struct timer_list *timer = &t->timer;
(void) del_timer(timer);
#endif
}
#endif
void CDECL
os_timer_init(os_timer_handler handler, void *data, int period)
{
os_timer *t = &global_state.timer;
t->handler = handler;
t->data = data;
t->period = period;
t->stop = 0;
#ifndef OS_KTHREAD
#ifdef OS_USE_SCHEDULE_DELAYED_WORK
INIT_WORK(&t->work, os_timer_bh, t);
#else
t->task.routine = os_timer_bh;
t->task.data = t;
/* initialize timer state */
init_timer(&t->timer);
t->timer.function = os_timer_internal;
t->timer.data = (ulong) t;
#endif
#endif
}
#ifdef OS_KTHREAD
static int os_timer_thread_loop(void *data)
{
os_timer *t = (os_timer *) data;
/* detach thread */
lock_kernel();
compat_daemonize("vmmemctl");
unlock_kernel();
/* we are running */
compat_complete(&t->notifyStart);
compat_set_freezable();
/* main loop */
while (1) {
/* sleep for specified period */
wait_event_interruptible_timeout(t->delay, t->stop, t->period);
compat_try_to_freeze();
if (t->stop) {
break;
}
/* execute registered handler */
(*(t->handler))(t->data);
}
/* terminate */
compat_complete_and_exit(&t->notifyStop, 0);
return(0);
}
static int os_timer_thread_start(os_timer *t)
{
os_status *s = &global_state.status;
/* initialize sync objects */
compat_init_completion(&t->notifyStart);
compat_init_completion(&t->notifyStop);
init_waitqueue_head(&t->delay);
/* create kernel thread */
t->pid = kernel_thread(os_timer_thread_loop, t, 0);
if (t->pid < 0) {
/* fail */
printk(KERN_WARNING "%s: unable to create kernel thread (%d)\n", s->name, t->pid);
return(-1);
}
if (OS_DEBUG) {
printk(KERN_DEBUG "%s: started kernel thread pid=%d\n", s->name, t->pid);
}
/* block until started... Why?! */
compat_wait_for_completion(&t->notifyStart);
return(0);
}
static void os_timer_thread_stop(os_timer *t)
{
wake_up_interruptible(&t->delay);
compat_wait_for_completion(&t->notifyStop);
}
#endif
void CDECL
os_timer_start(void)
{
os_timer *t = &global_state.timer;
/* clear termination flag */
t->stop = 0;
#ifdef OS_KTHREAD
os_timer_thread_start(t);
#else
os_timer_add(t);
#endif
}
void CDECL
os_timer_stop(void)
{
os_timer *t = &global_state.timer;
/* set termination flag */
t->stop = 1;
#ifdef OS_KTHREAD
os_timer_thread_stop(t);
#else
os_timer_remove(t);
#endif
}
unsigned int CDECL
os_timer_hz(void)
{
return HZ;
}
void CDECL
os_yield(void)
{
#ifdef OS_KTHREAD
cond_resched();
#else
/* Do nothing. Timer callbacks should not sleep. */
#endif
}
#ifdef CONFIG_PROC_FS
#ifdef VMW_USE_SEQ_FILE
static int os_proc_show(struct seq_file *f,
void *data)
{
os_status *s = &global_state.status;
char *buf = NULL;
int err = -1;
if (s->handler == NULL) {
err = 0;
goto out;
}
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (buf == NULL) {
err = -ENOMEM;
goto out;
}
s->handler(buf);
if (seq_puts(f, buf) != 0) {
err = -ENOSPC;
goto out;
}
err = 0;
out:
kfree(buf);
return err;
}
static int os_proc_open(struct inode *inode,
struct file *file)
{
return single_open(file, os_proc_show, NULL);
}
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
static int os_proc_read(char *buf,
char **start,
off_t offset,
int length)
#else
static int os_proc_read(char *buf,
char **start,
off_t offset,
int length,
int unused)
#endif
{
os_status *s = &global_state.status;
/* done if no handler */
if (s->handler == NULL) {
return(0);
}
/* invoke registered handler */
return(s->handler(buf));
}
#endif /* VMW_USE_SEQ_FILE */
#endif
void CDECL
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;
}
/* prevent module unload with extra reference */
if (OS_DISABLE_UNLOAD) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 48)
MOD_INC_USE_COUNT;
#else
try_module_get(THIS_MODULE);
#endif
}
/* zero global state */
memset(state, 0, sizeof(global_state));
/* initialize status state */
state->status.handler = handler;
state->status.name = name;
state->status.name_verbose = name_verbose;
#ifdef CONFIG_PROC_FS
/* register procfs device */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
global_proc_entry = create_proc_entry("vmmemctl", S_IFREG | S_IRUGO, NULL);
if (global_proc_entry != NULL) {
#ifdef VMW_USE_SEQ_FILE
global_proc_entry->proc_fops = &global_proc_fops;
#else
global_proc_entry->get_info = os_proc_read;
#endif /* VMW_USE_SEQ_FILE */
}
#else
proc_register(&proc_root, &global_proc_entry);
#endif
#endif /* CONFIG_PROC_FS */
/* log device load */
printk(KERN_INFO "%s initialized\n", state->status.name_verbose);
}
void CDECL
os_cleanup(void)
{
os_status *s = &global_state.status;
int err;
#ifdef CONFIG_PROC_FS
/* unregister procfs entry */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
remove_proc_entry("vmmemctl", NULL);
err = 0;
#else
if ((err = proc_unregister(&proc_root, global_proc_entry.low_ino)) != 0) {
printk(KERN_WARNING "%s: unable to unregister procfs entry (%d)\n", s->name, err);
}
#endif
#endif /* CONFIG_PROC_FS */
/* log device unload */
printk(KERN_INFO "%s unloaded\n", s->name_verbose);
}
/* Module information. */
MODULE_AUTHOR("VMware, Inc.");
MODULE_DESCRIPTION("VMware Memory Control Driver");
MODULE_LICENSE("GPL v2");
MODULE_VERSION(VMMEMCTL_DRIVER_VERSION_STRING);
/*
* Starting with SLE10sp2, Novell requires that IHVs sign a support agreement
* with them and mark their kernel modules as externally supported via a
* change to the module header. If this isn't done, the module will not load
* by default (i.e., neither mkinitrd nor modprobe will accept it).
*/
MODULE_INFO(supported, "external");
vmmemctl-only/vmmemctl_version.h 0000444 0000000 0000000 00000002251 12025726767 016135 0 ustar root root /*********************************************************
* 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
*
*********************************************************/
/*
* vmmemctl_version.h --
*
* Version definitions for the Linux memory ballooning driver.
*/
#ifndef _VMMEMCTL_VERSION_H_
#define _VMMEMCTL_VERSION_H_
#define VMMEMCTL_DRIVER_VERSION 1.0.1.0
#define VMMEMCTL_DRIVER_VERSION_COMMAS 1,0,1,0
#define VMMEMCTL_DRIVER_VERSION_STRING "1.0.1.0"
#endif /* _VMMEMCTL_VERSION_H_ */
vmmemctl-only/Makefile.kernel 0000444 0000000 0000000 00000003275 12025726767 015321 0 ustar root root #!/usr/bin/make -f
##########################################################
# 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
#
##########################################################
####
#### VMware vmballoon Makefile to be distributed externally
####
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, $(SRCROOT)/autoconf/setnice.c, -DVMW_HAVE_SET_USER_NICE, )
obj-m += $(DRIVER).o
$(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, $(wildcard $(SRCROOT)/*.c)))
#
# On a 32-bit machine, strip out 64-bit backdoor code, and vice versa.
#
ifeq ($(CONFIG_X86_64),y)
$(DRIVER)-y := $(filter-out backdoorGcc32.o, $($(DRIVER)-y))
else
$(DRIVER)-y := $(filter-out backdoorGcc64.o, $($(DRIVER)-y))
endif
clean:
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \
Module.symvers Modules.symvers Module.markers modules.order \
$(foreach dir,./,$(addprefix $(dir),.*.cmd .*.o.flags *.o)))
vmmemctl-only/Makefile.normal 0000444 0000000 0000000 00000005464 12025726767 015333 0 ustar root root #!/usr/bin/make -f
##########################################################
# 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
#
##########################################################
####
#### VMware vmmemctl Makefile to be distributed externally
####
vm_check_build = $(shell if $(CC) $(CC_OPTS) $(INCLUDE) \
-Werror -S -o /dev/null -xc $(1) \
> /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi)
DRIVERNAME = $(DRIVER)-$(VM_UNAME)
ifneq (,$(filter x86_64%, $(shell $(CC) -dumpmachine)))
MACHINE := x86_64
else
MACHINE := x386
endif
####
#### You must compile with at least -O level of optimization
#### or the module won't load.
#### If desparate, I think that bringing in might
#### suffice.
####
CC_WARNINGS := -Wall -Wstrict-prototypes
# Don't use -pipe or egcs-2.91.66 (shipped with RedHat) will die
CC_KFLAGS := -D__KERNEL__ -fno-strength-reduce -fno-omit-frame-pointer \
-fno-common -DKBUILD_MODNAME=$(DRIVER)
CC_KFLAGS += $(call vm_check_gcc,-falign-loops=2 -falign-jumps=2 -falign-functions=2, \
-malign-loops=2 -malign-jumps=2 -malign-functions=2)
CC_KFLAGS += $(call vm_check_gcc,-fno-strict-aliasing,)
ifeq ($(MACHINE),x86_64)
CC_KFLAGS += -mno-red-zone -mcmodel=kernel
else
# Gcc 3.0 deprecates -m486 --hpreg
CC_KFLAGS += -DCPU=586 $(call check_gcc,-march=i586,-m486)
endif
INCLUDE := -I$(HEADER_DIR)
INCLUDE += $(shell $(CC) $(CC_OPTS) $(INCLUDE) \
-E $(SRCROOT)/autoconf/geninclude.c \
| sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
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, )
OBJS += os.o
OBJS += vmballoon.o
ifeq ($(MACHINE),x86_64)
OBJS += backdoorGcc64.o
else
OBJS += backdoorGcc32.o
endif
CFLAGS := $(CC_OPTS) $(INCLUDE)
LIBS :=
default: all
all: ../$(DRIVER).o
$(DRIVERNAME): $(OBJS)
$(LD) -r -o $@ $^
$(DRIVER) $(DRIVER).o ../$(DRIVER).o: $(DRIVERNAME)
cp -f $< $@
auto-build: ../$(DRIVER).o
clean:
rm -f $(DRIVERNAME) ../$(DRIVERNAME) $(DRIVER) $(DRIVER).o ../$(DRIVER).o $(OBJS)
.SILENT:
vmmemctl-only/README 0000444 0000000 0000000 00000000705 12025726765 013253 0 ustar root root The files in this directory are the source files for the VMware
Memory Control driver. In order to build, make certain the
Makefile is correct, especially about whether or not your system is
multi-processor or not, and then just type:
make
from this directory. A copy of the module will be left in 'vmmemctl.o',
which can then be installed in /lib/modules//misc.
If you have any problems or questions, send mail to support@vmware.com
vmmemctl-only/Makefile 0000444 0000000 0000000 00000007266 12025726767 014046 0 ustar root root #!/usr/bin/make -f
##########################################################
# 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
#
##########################################################
####
#### VMware kernel module Makefile to be distributed externally
####
####
#### SRCROOT _must_ be a relative path.
####
SRCROOT = .
VM_UNAME = $(shell uname -r)
# Header directory for the running kernel
HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include
BUILD_DIR = $(HEADER_DIR)/..
DRIVER := vmmemctl
PRODUCT := @PRODUCT@
# Grep program
GREP = /bin/grep
vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi)
ifndef VM_KBUILD
VM_KBUILD := no
ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes)
ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes)
VM_KBUILD := 26
endif
endif
export VM_KBUILD
endif
ifndef VM_KBUILD_SHOWN
ifeq ($(VM_KBUILD), no)
VM_DUMMY := $(shell echo >&2 "Using standalone build system.")
else
ifeq ($(VM_KBUILD), 24)
VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.")
else
VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.")
endif
endif
VM_KBUILD_SHOWN := yes
export VM_KBUILD_SHOWN
endif
ifneq ($(VM_KBUILD), no)
VMCCVER := $(shell $(CC) -dumpversion)
# If there is no version defined, we are in toplevel pass, not yet in kernel makefiles...
ifeq ($(VERSION),)
ifeq ($(VM_KBUILD), 24)
DRIVER_KO := $(DRIVER).o
else
DRIVER_KO := $(DRIVER).ko
endif
.PHONY: $(DRIVER_KO)
auto-build: $(DRIVER_KO)
cp -f $< $(SRCROOT)/../$(DRIVER).o
# $(DRIVER_KO) is a phony target, so compare file times explicitly
$(DRIVER): $(DRIVER_KO)
if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi
# Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler
VM_CCVER := $(VMCCVER)
export VM_CCVER
VM_CC := $(CC)
export VM_CC
MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES))
#
# Define a setup target that gets built before the actual driver.
# This target may not be used at all, but if it is then it will be defined
# in Makefile.kernel
#
prebuild:: ;
postbuild:: ;
$(DRIVER_KO): prebuild
make -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) modules
make -C $$PWD SRCROOT=$$PWD/$(SRCROOT) postbuild
endif
vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \
$(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \
$(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \
-DKBUILD_BASENAME=\"$(DRIVER)\" \
-Werror -S -o /dev/null -xc $(1) \
> /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi)
CC_WARNINGS := -Wall -Wstrict-prototypes
CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD
ifdef VMX86_DEVEL
CC_OPTS += -DVMX86_DEVEL
endif
ifdef VMX86_DEBUG
CC_OPTS += -DVMX86_DEBUG
endif
include $(SRCROOT)/Makefile.kernel
ifdef TOPDIR
ifeq ($(VM_KBUILD), 24)
O_TARGET := $(DRIVER).o
obj-y := $($(DRIVER)-y)
include $(TOPDIR)/Rules.make
endif
endif
else
include $(SRCROOT)/Makefile.normal
endif
#.SILENT:
vmmemctl-only/COPYING 0000444 0000000 0000000 00000043103 12025726766 013426 0 ustar root root GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 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.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, 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 or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
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 give any other recipients of the Program a copy of this License
along with the Program.
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 Program or any portion
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
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 Program, 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 Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) 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; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, 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 executable. However, as a
special exception, the source code 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.
If distribution of executable or 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 counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program 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.
5. 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 Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program 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 to
this License.
7. 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 Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program 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 Program.
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.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program 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.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 Program
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 Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, 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
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), 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 Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. 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.
Copyright (C)
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; either version 2 of the License, or
(at your option) any 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.