Compare commits
46
Commits
w14.0.0
...
w12.5.9-k5.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bf64bcf51 | ||
|
|
a0015e124f | ||
|
|
732a24adc2 | ||
|
|
01a4684c73 | ||
|
|
c1fcc29bad | ||
|
|
1ece889abb | ||
|
|
5a42a413e1 | ||
|
|
3219caddfd | ||
|
|
1b1fc503d8 | ||
|
|
c397f07f83 | ||
|
|
ddb6d47ed0 | ||
|
|
8bfd4ebfa2 | ||
|
|
b5392bc630 | ||
|
|
85ede6aae9 | ||
|
|
6c9f69c157 | ||
|
|
d20641f619 | ||
|
|
a0058c6958 | ||
|
|
ffed1804ea | ||
|
|
5db3c8a86f | ||
|
|
c3fb5cda19 | ||
|
|
1359beeff3 | ||
|
|
6d4b845097 | ||
|
|
395e1b04b9 | ||
|
|
a66676a086 | ||
|
|
16c49e52d4 | ||
|
|
d3d0633eb9 | ||
|
|
f2fb742504 | ||
|
|
77a6966b97 | ||
|
|
56817b60cb | ||
|
|
14d62f54c5 | ||
|
|
06ae436b38 | ||
|
|
c10d5901ae | ||
|
|
625084e96a | ||
|
|
1d91cc5b6a | ||
|
|
6fd497d954 | ||
|
|
3fc524fd27 | ||
|
|
6bf216788a | ||
|
|
83ee5c77e0 | ||
|
|
92152dbb21 | ||
|
|
7bf4fae2e0 | ||
|
|
5fd98702de | ||
|
|
430a7d0252 | ||
|
|
3d675157b6 | ||
|
|
aafa7a346f | ||
|
|
54a7a75068 | ||
|
|
e2d569abf1 |
No files matched your search
@@ -3,6 +3,8 @@
|
||||
*.ko
|
||||
*.ko.cmd
|
||||
*.mod.c
|
||||
*.tar
|
||||
.tmp_versions
|
||||
.cache.mk
|
||||
Module.symvers
|
||||
modules.order
|
||||
@@ -0,0 +1,197 @@
|
||||
This document explains how to use the repository to retrieve the module
|
||||
source, build modules and install them. There are two basic methods: we can
|
||||
either build the modules from source and install them ourselves or replace
|
||||
VMware provided source tarballs with patched ones and let it use its own
|
||||
vmware-modconfig tool.
|
||||
|
||||
|
||||
0. Quick guide for impatient
|
||||
----------------------------
|
||||
|
||||
First method (build and install):
|
||||
|
||||
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-14.1.1.tar.gz
|
||||
tar -xzf workstation-14.1.1.tar.gz
|
||||
cd vmware-host-modules-workstation-14.1.1
|
||||
make
|
||||
make install
|
||||
|
||||
Last command must be executed with root privileges (first four shouldn't).
|
||||
Based on your VMware product, replace "14.1.1" with your installed version
|
||||
and/or "workstation" with "player".
|
||||
|
||||
Second method (replace original tarballs):
|
||||
|
||||
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-14.1.1.tar.gz
|
||||
tar -xzf workstation-14.1.1.tar.gz
|
||||
cd vmware-host-modules-workstation-14.1.1
|
||||
tar -cf vmmon.tar vmmon-only
|
||||
tar -cf vmnet.tar vmnet-only
|
||||
cp -v vmmon.tar vmnet.tar /usr/lib/vmware/modules/source/
|
||||
vmware-modconfig --console --install-all
|
||||
|
||||
In this case, last two commands require root privileges.
|
||||
|
||||
|
||||
1a. Retrieve the source - with git
|
||||
----------------------------------
|
||||
|
||||
Using git is preferrable as it allows an easy switch to sources for
|
||||
different product/version or update for newer kernel version. Without git,
|
||||
you can only download one particular source snapshot.
|
||||
|
||||
First, clone the repository from GitHub either using HTTPS
|
||||
|
||||
git clone https://github.com/mkubecek/vmware-host-modules.git
|
||||
|
||||
or using SSH
|
||||
|
||||
git clone git@github.com:mkubecek/vmware-host-modules.git
|
||||
|
||||
Using SSH is preferrable if you already have an account on GitHub, use
|
||||
HTTPS if you don't.
|
||||
|
||||
Branch "master" cannot be used to build modules, it contains only common
|
||||
files so that changes in them can be merged into all other branches easily.
|
||||
To get actual sources, checkout a "real" branch, e.g.
|
||||
|
||||
git checkout workstation-14.1.1
|
||||
|
||||
Branch name consists of "workstation" (for Workstation) or "player" (for
|
||||
Player), a dash and version number ("14.1.1" here). Always use correct
|
||||
product and version, the modules check if internal source version matches
|
||||
installed product and refuse to load otherwise. Actually, in all recent
|
||||
versions, "workstation" and "player" sources have been identical but there
|
||||
is no guarantee it will always be the case.
|
||||
|
||||
To pull out updated branch (if there are new commits), run "git pull", to
|
||||
switch to a new branch run "git fetch" and "git checkout ...".
|
||||
|
||||
|
||||
1b. Retrieve the source - without git
|
||||
-------------------------------------
|
||||
|
||||
GitHub allows to download a particular snapshot (branch or tag) directly
|
||||
without git:
|
||||
|
||||
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-14.1.1.tar.gz
|
||||
|
||||
where "workstation" and "14.1.1" have the same meaning as in section 1a.
|
||||
Any other tool can be used to retrieve the URL, of course. It's also
|
||||
possible to download directly from the web interface, switch to the branch
|
||||
you are interested in, click the "Clone or download" button and then
|
||||
"Download ZIP".
|
||||
|
||||
Unpack the downloaded archive
|
||||
|
||||
tar -xzf workstation-14.1.1.tar.gz
|
||||
|
||||
or
|
||||
|
||||
unzip vmware-host-modules-workstation-14.1.1.zip
|
||||
|
||||
depending on archive type. Then change to the resulting directory.
|
||||
|
||||
|
||||
2a. Build and install modules - directly
|
||||
----------------------------------------
|
||||
|
||||
To build modules against currently running kernel, just run "make" in top
|
||||
level directory. It creates two module files vmmon-only/vmmon.ko and
|
||||
vmnet-only/vmnet.ko (unstripped). To build against a different kernel, set
|
||||
variable VM_UNAME, e.g.
|
||||
|
||||
make VM_UNAME='4.14.15-5-default'
|
||||
|
||||
As name suggests, this variable should be set to what "uname -r" would show
|
||||
when that kernel is booted (it's the same as name of the subdirectory under
|
||||
/lib/modules with modules of that kernel).
|
||||
|
||||
To install built modules for currently running kernel, run "make install".
|
||||
This command needs to be run as user with permissions to write into the
|
||||
directory with kernel modules (under normal circumstances, this should be
|
||||
only root). The VM_UNAME variable can be used to install for a different
|
||||
kernel. Unless you know well what are you doing and why, the same value
|
||||
should be always used for "make" and "make install". That's why makefile
|
||||
checks if vermagic tag of the moudules match VM_UNAME (or current kernel if
|
||||
VM_UNAME isn't set).
|
||||
|
||||
If DESTDIR is not set (or is empty), "make install" also runs depmod to
|
||||
update module dependency cache.
|
||||
|
||||
Note that "make install" replaces existing module files but it does not
|
||||
replace modules in running kernel if they are already loaded. Reloading the
|
||||
modules can be enforced e.g. by
|
||||
|
||||
/etc/init.d/vmware restart
|
||||
|
||||
All running VMs should be turned off before this.
|
||||
|
||||
|
||||
2b. Build and install modules - replacing the original source tarballs
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Manual build and installation of host modules may be natural for developers
|
||||
and power users but those who prefer to "just use" would appreciate if they
|
||||
could rely on standard VMware tools. To this goal, we need to replace the
|
||||
module source tarballs with patched versions.
|
||||
|
||||
In local checked out repository, the replacement tarballs can be created
|
||||
with
|
||||
|
||||
make tarballs
|
||||
|
||||
This command creates files vmmon.tar and vmnet.tar which can be used to
|
||||
replace the original tarballs provided with the VMware product. Note that
|
||||
this command creates the tarball from current HEAD (in git language), i.e.
|
||||
they do not contain any uncommited local changes (e.g. files created by
|
||||
test build).
|
||||
|
||||
When using a downloaded tarball, simply run
|
||||
|
||||
tar -cf vmmon.tar vmmon-only
|
||||
tar -cf vmnet.tar vmnet-only
|
||||
|
||||
to create the tarballs. In this case, there is no protection against
|
||||
unwanted local changes.
|
||||
|
||||
Whatever way you used to create the tarballs, replace the original ones
|
||||
provided by VMware
|
||||
|
||||
/usr/lib/vmware/modules/source/vmmon.tar
|
||||
/usr/lib/vmware/modules/source/vmnet.tar
|
||||
|
||||
by patched versions. It is highly recommended to backup the original
|
||||
tarballs before replacing them.
|
||||
|
||||
Once patched tarballs are installed, you can rebuild the modules as usual:
|
||||
|
||||
vmware-modconfig --console --install-all
|
||||
|
||||
or let the GUI run the command for you.
|
||||
|
||||
Replacing the original tarballs prevents having to rebuild and install the
|
||||
modules manually with every new kernel version. However, once the VMware
|
||||
product is upgraded or reinstalled, tarballs are replaced so that if the
|
||||
new VMware version doesn't build/work with a recent kernel, you still need
|
||||
to repeat the process. The same also holds if there is a new kernel which
|
||||
requires updated version of the patches.
|
||||
|
||||
|
||||
3. Final notes
|
||||
--------------
|
||||
|
||||
Always make sure that you are using a branch matching the Workstation or
|
||||
Player version you are running. VMware software may refuse to start if
|
||||
module intended for different version is loaded. And unless you have
|
||||
a reason not to, use current head of that branch; even if the module
|
||||
builds, there may still be later fixes which may be important.
|
||||
|
||||
In some web forums, one can comments suggesting to rip out one patched file
|
||||
and use it as replacement for the corresponding file with VMware tarballs.
|
||||
Please don't do this - and if you do, don't complain if something doesn't
|
||||
work. A commit fixing some problem is meant to be used as a whole; picking
|
||||
just changes in one file can lead to rather unpredictable results. While
|
||||
picking just one commit (or some of the commits) in a branch is perfectly
|
||||
fine (you should still know what are you doing and why), picking just one
|
||||
patched file rarely makes sense.
|
||||
@@ -0,0 +1,49 @@
|
||||
MODULES = vmmon vmnet
|
||||
SUBDIRS = $(MODULES:%=%-only)
|
||||
TARBALLS = $(MODULES:%=%.tar)
|
||||
MODFILES = $(foreach mod,$(MODULES),$(mod)-only/$(mod).ko)
|
||||
VM_UNAME = $(shell uname -r)
|
||||
MODDIR = /lib/modules/$(VM_UNAME)/misc
|
||||
|
||||
MODINFO = /sbin/modinfo
|
||||
DEPMOD = /sbin/depmod
|
||||
|
||||
%.tar: FORCE gitcleancheck
|
||||
git archive -o $@ --format=tar HEAD $(@:.tar=-only)
|
||||
|
||||
.PHONY: FORCE subdirs $(SUBDIRS) clean tarballs
|
||||
|
||||
subdirs: retiredcheck $(SUBDIRS)
|
||||
|
||||
FORCE:
|
||||
|
||||
$(SUBDIRS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
||||
gitcheck:
|
||||
@git status >/dev/null 2>&1 \
|
||||
|| ( echo "This only works in a git repository."; exit 1 )
|
||||
|
||||
gitcleancheck: gitcheck
|
||||
@git diff --exit-code HEAD >/dev/null 2>&1 \
|
||||
|| echo "Warning: tarballs will reflect current HEAD (no uncommited changes)"
|
||||
|
||||
retiredcheck:
|
||||
@test -f RETIRED && cat RETIRED || true
|
||||
|
||||
install: retiredcheck $(MODFILES)
|
||||
@for f in $(MODFILES); do \
|
||||
mver=$$($(MODINFO) -F vermagic $$f);\
|
||||
mver=$${mver%% *};\
|
||||
test "$${mver}" = "$(VM_UNAME)" \
|
||||
|| ( echo "Version mismatch: module $$f $${mver}, kernel $(VM_UNAME)" ; exit 1 );\
|
||||
done
|
||||
install -D -t $(DESTDIR)$(MODDIR) $(MODFILES)
|
||||
strip --strip-debug $(MODULES:%=$(DESTDIR)$(MODDIR)/%.ko)
|
||||
if test -z "$(DESTDIR)"; then $(DEPMOD) -a $(VM_UNAME); fi
|
||||
|
||||
clean: $(SUBDIRS)
|
||||
rm -f *.o
|
||||
|
||||
tarballs: $(TARBALLS)
|
||||
|
||||
@@ -12,12 +12,17 @@ a particular version of Player or Workstation.
|
||||
|
||||
From these tags, branches "player-${version}" and "workstation-${version}"
|
||||
are forked. These branches track changes needed to build these modules
|
||||
against recent kernel versions. Tag "p${ver}-k${ver}" marks the set of
|
||||
changes needed to build modules from Player ${ver} against kernel ${ver},
|
||||
against recent kernel versions. Tag "p${ver}-k${kver}" marks the set of
|
||||
changes needed to build modules from Player ${ver} against kernel ${kver},
|
||||
e.g. p12.5.5-k4.11 is for Player 12.5.5 and kernel 4.11; similar naming
|
||||
scheme "w${ver}-k${kver}" is used for Workstation modules. In general,
|
||||
later points in the branch should also work with older kernels (e.g.
|
||||
p12.5.5-k4.11 with kernel 4.10) but it's not completely reliable.
|
||||
p12.5.5-k4.11 with kernel 4.10) but it's not guaranteed; it may happen that
|
||||
a fix for new kernel version may be too complicated to make also work with
|
||||
older versions.
|
||||
|
||||
At the moment, changes are tested to build against all (vanilla) kernel
|
||||
releases starting with 4.9.
|
||||
|
||||
This repository is provided "as is" with no guarantees. Use the contents on
|
||||
your own risk.
|
||||
+1
-1
@@ -117,7 +117,7 @@ prebuild:: ;
|
||||
postbuild:: ;
|
||||
|
||||
$(DRIVER_KO): prebuild
|
||||
$(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
|
||||
$(MAKE) -C $(BUILD_DIR) M=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
|
||||
MODULEBUILDDIR=$(MODULEBUILDDIR) modules
|
||||
$(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \
|
||||
MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild
|
||||
|
||||
@@ -33,7 +33,7 @@ $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, \
|
||||
$(wildcard $(SRCROOT)/linux/*.c $(SRCROOT)/common/*.c $(SRCROOT)/vmcore/*.c)))
|
||||
|
||||
clean:
|
||||
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \
|
||||
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions .cache.mk \
|
||||
Module.symvers Modules.symvers Module.markers modules.order \
|
||||
$(foreach dir,linux/ common/ vmcore/ \
|
||||
./,$(addprefix $(dir),.*.cmd .*.o.flags *.o)))
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998,2018 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -35,6 +35,7 @@
|
||||
uint32 cpuidFeatures;
|
||||
static CpuidVendor vendor = CPUID_NUM_VENDORS;
|
||||
static uint32 version;
|
||||
static Bool hasSpecCtrl;
|
||||
|
||||
|
||||
/*
|
||||
@@ -97,6 +98,9 @@ CPUID_Init(void)
|
||||
Warning("VMMON CPUID: Unrecognized CPU\n");
|
||||
vendor = CPUID_VENDOR_UNKNOWN;
|
||||
}
|
||||
|
||||
__GET_CPUID2(7, 0, ®s);
|
||||
hasSpecCtrl = vendor == CPUID_VENDOR_INTEL && ((regs.edx >> 26) & 0x3) != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -207,3 +211,26 @@ CPUID_AddressSizeSupported(void)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* CPUID_HostSupportsSpecCtrl --
|
||||
*
|
||||
* Determine whether the processor supports MSR_SPEC_CTRL.
|
||||
*
|
||||
* Results:
|
||||
* True iff the processor supports the required features.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Bool
|
||||
CPUID_HostSupportsSpecCtrl(void)
|
||||
{
|
||||
return hasSpecCtrl;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998,2016 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998,2016,2018 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -39,6 +39,7 @@ uint32 CPUID_GetVersion(void);
|
||||
Bool CPUID_SyscallSupported(void);
|
||||
Bool CPUID_LongModeSupported(void);
|
||||
Bool CPUID_AddressSizeSupported(void);
|
||||
Bool CPUID_HostSupportsSpecCtrl(void);
|
||||
|
||||
static INLINE uint32
|
||||
CPUID_GetFeatures(void)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998-2018 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -79,6 +79,9 @@
|
||||
# define USE_TEMPORARY_GDT 0
|
||||
#endif
|
||||
|
||||
/* Cycle through values of SPEC_CTRL and verify they survive world switch. */
|
||||
#undef CYCLE_SPEC_CTRL
|
||||
|
||||
#define TS_ASSERT(t) do { \
|
||||
DEBUG_ONLY(if (!(t)) TaskAssertFail(__LINE__);) \
|
||||
} while (0)
|
||||
@@ -1594,12 +1597,23 @@ TaskSwitchToMonitor(VMCrossPage *crosspage)
|
||||
{
|
||||
uint64 raxGetsWiped, rcxGetsWiped;
|
||||
|
||||
#ifdef CALL_NOSPEC
|
||||
__asm__ __volatile__(CALL_NOSPEC
|
||||
: "=a" (raxGetsWiped),
|
||||
"=c" (rcxGetsWiped)
|
||||
: "0" (codePtr),
|
||||
"1" (crosspage),
|
||||
THUNK_TARGET(codePtr)
|
||||
: "rdx", "r8", "r9", "r10", "r11", "cc", "memory");
|
||||
#else
|
||||
__asm__ __volatile__("call *%%rax"
|
||||
: "=a" (raxGetsWiped),
|
||||
"=c" (rcxGetsWiped)
|
||||
: "0" (codePtr),
|
||||
"1" (crosspage)
|
||||
: "rdx", "r8", "r9", "r10", "r11", "cc", "memory");
|
||||
#endif
|
||||
|
||||
}
|
||||
#elif defined(_MSC_VER)
|
||||
/*
|
||||
@@ -1764,6 +1778,11 @@ Task_Switch(VMDriver *vm, // IN
|
||||
uint32 pCPU;
|
||||
MPN hvRootMPN;
|
||||
Descriptor *tempGDTBase;
|
||||
#ifdef CYCLE_SPEC_CTRL
|
||||
Bool specCtrlEqual = FALSE;
|
||||
uint64 readSpecCtrlValue = 0;
|
||||
static volatile uint64 currentSpecCtrlValue = 0;
|
||||
#endif
|
||||
|
||||
ASSERT_ON_COMPILE(sizeof(VMCrossPage) == PAGE_SIZE);
|
||||
TaskDisableNMI(&vm->hostAPIC, &lint0NMI, &lint1NMI, &pcNMI, &thermalNMI);
|
||||
@@ -1973,6 +1992,14 @@ Task_Switch(VMDriver *vm, // IN
|
||||
TS_ASSERT(SELECTOR_TABLE(ds) == SELECTOR_GDT);
|
||||
TS_ASSERT(SELECTOR_TABLE(ss) == SELECTOR_GDT);
|
||||
|
||||
if (CPUID_HostSupportsSpecCtrl()) {
|
||||
#ifdef CYCLE_SPEC_CTRL
|
||||
currentSpecCtrlValue = (currentSpecCtrlValue + 1) % 4;
|
||||
__SET_MSR(MSR_SPEC_CTRL, currentSpecCtrlValue);
|
||||
#endif
|
||||
crosspage->crosspageData.specCtrl = __GET_MSR(MSR_SPEC_CTRL);
|
||||
}
|
||||
|
||||
DEBUG_ONLY(crosspage->crosspageData.tinyStack[0] = 0xDEADBEEF;)
|
||||
/* Running in host context prior to TaskSwitchToMonitor() */
|
||||
TaskSwitchToMonitor(crosspage);
|
||||
@@ -1980,6 +2007,16 @@ Task_Switch(VMDriver *vm, // IN
|
||||
|
||||
TS_ASSERT(crosspage->crosspageData.tinyStack[0] == 0xDEADBEEF);
|
||||
|
||||
#ifdef CYCLE_SPEC_CTRL
|
||||
if (CPUID_HostSupportsSpecCtrl()) {
|
||||
readSpecCtrlValue = __GET_MSR(MSR_SPEC_CTRL);
|
||||
specCtrlEqual = readSpecCtrlValue ==
|
||||
crosspage->crosspageData.specCtrl;
|
||||
/* Do not leak cycling SPEC_CTRL value back to host. */
|
||||
__SET_MSR(MSR_SPEC_CTRL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Temporarily disable single-step stress as VMX/VMCS change code
|
||||
* ASSERTS on RFLAGS content without allowing TF/RF to be set.
|
||||
@@ -2113,6 +2150,12 @@ Task_Switch(VMDriver *vm, // IN
|
||||
if (UNLIKELY(TaskGotException(crosspage, EXC_UD))) {
|
||||
Warning("#UD occurred on switch back to host; dumping core");
|
||||
}
|
||||
#ifdef CYCLE_SPEC_CTRL
|
||||
if (UNLIKELY(!specCtrlEqual)) {
|
||||
Warning("SpecCtrl not equal: expected %"FMT64"x, got %"FMT64"x\n",
|
||||
crosspage->crosspageData.specCtrl, readSpecCtrlValue);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* The NMI/MCE checks above are special cases for interrupts
|
||||
* received during worldswitch. Here is the more generic case
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef __COMPAT_MMAP_LOCK_H__
|
||||
#define __COMPAT_MMAP_LOCK_H__
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
* In 5.8-rc1, mmap locking was reworked to use wrappers around mmap_sem
|
||||
* (which was also renamed to mmap_lock). All code is now supposed to use
|
||||
* these wrappers as the internal implementation of the lock may change in
|
||||
* the future.
|
||||
*
|
||||
* Check also _LINUX_MMAP_LOCK_H to handle possible backports to distribution
|
||||
* pre-5.8 kernel. This macro is defined in <linux/mmap_lock.h> which is also
|
||||
* included in <linux/mm.h> since the commit introducing the wrappers so that
|
||||
* we should have it defined in any kernel providing the new API.
|
||||
*/
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) || defined(_LINUX_MMAP_LOCK_H)
|
||||
#include <linux/mmap_lock.h>
|
||||
#else
|
||||
|
||||
static inline void mmap_read_lock(struct mm_struct *mm)
|
||||
{
|
||||
down_read(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
static inline void mmap_read_unlock(struct mm_struct *mm)
|
||||
{
|
||||
up_read(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
#endif /* 5.8.0 */
|
||||
|
||||
#endif /* __COMPAT_MMAP_LOCK_H__ */
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef __COMPAT_POLL_H__
|
||||
#define __COMPAT_POLL_H__
|
||||
|
||||
#include <linux/poll.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0))
|
||||
|
||||
#ifndef __poll_t
|
||||
typedef unsigned int __poll_t;
|
||||
#endif
|
||||
|
||||
static inline __poll_t compat_vfs_poll(struct file *file,
|
||||
struct poll_table_struct *pt)
|
||||
{
|
||||
if (unlikely(!file->f_op->poll))
|
||||
return DEFAULT_POLLMASK;
|
||||
return file->f_op->poll(file, pt);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline __poll_t compat_vfs_poll(struct file *file,
|
||||
struct poll_table_struct *pt)
|
||||
{
|
||||
return vfs_poll(file, pt);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __COMPAT_POLL_H__ */
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef __COMPAT_TIMER_H__
|
||||
# define __COMPAT_TIMER_H__
|
||||
|
||||
#include <linux/timer.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) && !defined(timer_setup)
|
||||
|
||||
typedef unsigned long compat_timer_arg_t;
|
||||
|
||||
static inline void compat_timer_setup(struct timer_list *timer,
|
||||
void (*func)(compat_timer_arg_t),
|
||||
unsigned int flags)
|
||||
{
|
||||
init_timer(timer);
|
||||
timer->function = func;
|
||||
timer->data = 0;
|
||||
timer->flags = flags;
|
||||
}
|
||||
|
||||
#else /* new timer interface since 4.15 */
|
||||
|
||||
typedef struct timer_list *compat_timer_arg_t;
|
||||
|
||||
static inline void compat_timer_setup(struct timer_list *timer,
|
||||
void (*func)(compat_timer_arg_t),
|
||||
unsigned int flags)
|
||||
{
|
||||
timer_setup(timer, func, flags);
|
||||
}
|
||||
|
||||
#endif /* new timer interface since 4.15 */
|
||||
|
||||
#endif /* __COMPAT_TIMER_H__ */
|
||||
@@ -251,6 +251,7 @@ static INLINE ub8 hash2(register const ub8 *k, /* the key */
|
||||
{
|
||||
/* c is reserved for the length */
|
||||
case 2: b+=k[1];
|
||||
/* fall through */
|
||||
case 1: a+=k[0];
|
||||
/* case 0: nothing left to add */
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998-2015,2018 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -133,7 +133,7 @@ PtrToVA64(void const *ptr) // IN
|
||||
*
|
||||
*/
|
||||
|
||||
#define VMMON_VERSION (308 << 16 | 0)
|
||||
#define VMMON_VERSION (309 << 16 | 0)
|
||||
#define VMMON_VERSION_MAJOR(v) ((uint32) (v) >> 16)
|
||||
#define VMMON_VERSION_MINOR(v) ((uint16) (v))
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998-2015,2018 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -421,6 +421,7 @@ struct VMCrossPageData {
|
||||
*/
|
||||
uint8 switchHostIDT [sizeof(Gate64) * NUM_EXCEPTIONS]; // hostCS:hostVA
|
||||
uint8 switchMon64IDT[sizeof(Gate64) * NUM_EXCEPTIONS]; // 64-bit monCS:monVA
|
||||
uint64 specCtrl; /* host MSR_SPEC_CTRL value before world switch. */
|
||||
}
|
||||
#include "vmware_pack_end.h"
|
||||
VMCrossPageData;
|
||||
@@ -474,7 +475,7 @@ struct VMCrossPage {
|
||||
#include "vmware_pack_end.h"
|
||||
VMCrossPage;
|
||||
|
||||
#define CROSSPAGE_VERSION_BASE 0xbf1 /* increment by 1 */
|
||||
#define CROSSPAGE_VERSION_BASE 0xbf2 /* increment by 1 */
|
||||
#define CROSSPAGE_VERSION ((CROSSPAGE_VERSION_BASE << 1) + WS_INTR_STRESS)
|
||||
|
||||
#if !defined(VMX86_SERVER) && defined(VMM)
|
||||
|
||||
@@ -67,6 +67,7 @@ extern "C" {
|
||||
#if defined (VMKPANIC)
|
||||
#include "vmk_assert.h"
|
||||
#else /* !VMKPANIC */
|
||||
#include <linux/kernel.h>
|
||||
#define _ASSERT_PANIC(name) \
|
||||
Panic(_##name##Fmt "\n", __FILE__, __LINE__)
|
||||
#define _ASSERT_PANIC_BUG(bug, name) \
|
||||
@@ -118,7 +119,7 @@ NORETURN void Panic_NoSaveNoReturn(const char *fmt, ...) PRINTF_DECL(1, 2);
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2);
|
||||
#define Panic panic
|
||||
#endif
|
||||
|
||||
void LogThrottled(uint32 *count, const char *fmt, ...) PRINTF_DECL(2, 3);
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#define INCLUDE_ALLOW_VMCORE
|
||||
#include "includeCheck.h"
|
||||
|
||||
#include <asm/processor-flags.h>
|
||||
|
||||
#define X86_MAX_INSTR_LEN 15 /* Max byte length of an x86 instruction. */
|
||||
|
||||
#define NUM_IDT_VECTORS 256
|
||||
@@ -62,7 +64,9 @@
|
||||
#define CR3_PDB_MASK 0xfffff000
|
||||
#define CR3_IGNORE 0xFFF
|
||||
#define PAE_CR3_IGNORE 0x1F
|
||||
#ifndef CR3_PCID_MASK
|
||||
#define CR3_PCID_MASK 0xFFF
|
||||
#endif
|
||||
#define CR3_NO_FLUSH (1ULL << 63)
|
||||
|
||||
#define CR4_VME 0x00000001
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2016 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -419,6 +419,10 @@ FIELD( 6, 0, EBX, 0, 4, NUM_INTR_THRESHOLDS, NA, FALSE) \
|
||||
FLAG( 6, 0, ECX, 0, 1, HW_COORD_FEEDBACK, NA, FALSE) \
|
||||
FLAG( 6, 0, ECX, 3, 1, ENERGY_PERF_BIAS, NA, FALSE)
|
||||
|
||||
#define CPUID_7_EDX_26 \
|
||||
FLAG( 7, 0, EDX, 26, 1, LEVEL7EDX_RSVD1, NO, FALSE)
|
||||
#define CPUID_7_EDX_27 \
|
||||
FLAG( 7, 0, EDX, 27, 1, LEVEL7EDX_RSVD2, NO, FALSE)
|
||||
|
||||
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */
|
||||
#define CPUID_FIELD_DATA_LEVEL_7 \
|
||||
@@ -440,8 +444,9 @@ FLAG( 7, 0, EBX, 18, 1, RDSEED, YES, TRUE) \
|
||||
FLAG( 7, 0, EBX, 19, 1, ADX, YES, TRUE) \
|
||||
FLAG( 7, 0, EBX, 20, 1, SMAP, YES, FALSE) \
|
||||
FLAG( 7, 0, EBX, 25, 1, PT, NO, FALSE) \
|
||||
FLAG( 7, 0, ECX, 0, 1, PREFETCHWT1, NO, TRUE)
|
||||
|
||||
FLAG( 7, 0, ECX, 0, 1, PREFETCHWT1, NO, TRUE) \
|
||||
CPUID_7_EDX_26 \
|
||||
CPUID_7_EDX_27
|
||||
|
||||
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, CPL3 */
|
||||
#define CPUID_FIELD_DATA_LEVEL_A \
|
||||
@@ -708,6 +713,7 @@ FIELD( 84, 0, EBX, 0, 32, LEAF84_BRAND_STRING_EBX, NA, FALSE) \
|
||||
FIELD( 84, 0, ECX, 0, 32, LEAF84_BRAND_STRING_ECX, NA, FALSE) \
|
||||
FIELD( 84, 0, EDX, 0, 32, LEAF84_BRAND_STRING_EDX, NA, FALSE)
|
||||
|
||||
|
||||
#define CPUID_8A_EDX_11 \
|
||||
FLAG( 8A, 0, EDX, 11, 1, SVMEDX_RSVD1, NO, FALSE)
|
||||
#define CPUID_8A_EDX_14_31 \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2003-2015 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 2003-2015,2018 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -63,6 +63,14 @@ extern "C" {
|
||||
*/
|
||||
void __cpuid(int regs[4], int eax);
|
||||
#pragma intrinsic(__cpuid)
|
||||
|
||||
/*
|
||||
* __cpuidex has been supported since VS2008
|
||||
*/
|
||||
#if _MSC_VER >= 1500
|
||||
void __cpuidex(int regs[4], int eax, int ecx);
|
||||
#pragma intrinsic(__cpuidex)
|
||||
#endif /* _MSC_VER >= 1500 */
|
||||
#endif /* VM_X86_64 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -247,6 +255,20 @@ __GET_CPUID(int input, CPUIDRegs *regs)
|
||||
|
||||
#ifdef VM_X86_64
|
||||
|
||||
#if _MSC_VER >= 1500
|
||||
|
||||
/*
|
||||
* __cpuidex has been supported since VS2008
|
||||
*/
|
||||
|
||||
static INLINE void
|
||||
__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs)
|
||||
{
|
||||
__cpuidex((int *)regs, inputEax, inputEcx);
|
||||
}
|
||||
|
||||
#else // _MSC_VER >= 1500
|
||||
|
||||
/*
|
||||
* No inline assembly in Win64. Implemented in bora/lib/misc in
|
||||
* cpuidMasm64.asm.
|
||||
@@ -254,6 +276,7 @@ __GET_CPUID(int input, CPUIDRegs *regs)
|
||||
|
||||
extern void
|
||||
__GET_CPUID2(int inputEax, int inputEcx, CPUIDRegs *regs);
|
||||
#endif // _MSC_VER >= 1500
|
||||
|
||||
#else // VM_X86_64
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998-2018 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#ifndef _X86MSR_H_
|
||||
#define _X86MSR_H_
|
||||
#include <asm/msr-index.h>
|
||||
#define INCLUDE_ALLOW_USERLEVEL
|
||||
#define INCLUDE_ALLOW_VMX
|
||||
|
||||
@@ -79,6 +80,7 @@ MSRQuery;
|
||||
#define MSR_SMI_COUNT 0x00000034 // Intel Nehalem Family
|
||||
#define MSR_FEATCTL 0x0000003a
|
||||
#define MSR_TSC_ADJUST 0x0000003b
|
||||
#define MSR_SPEC_CTRL 0x00000048
|
||||
#define MSR_BIOS_UPDT_TRIG 0x00000079
|
||||
#define MSR_BIOS_SIGN_ID 0x0000008b
|
||||
#define MSR_PERFCTR0 0x000000c1
|
||||
@@ -106,7 +108,10 @@ MSRQuery;
|
||||
#define MSR_TSC_AUX 0xc0000103
|
||||
#define MSR_BD_TSC_RATIO 0xc0000104
|
||||
|
||||
|
||||
#ifndef MSR_MISC_FEATURES_ENABLES
|
||||
#define MSR_MISC_FEATURES_ENABLES 0x140
|
||||
#endif
|
||||
|
||||
/* Intel Core Architecture and later: use only architected counters. */
|
||||
#define IA32_MSR_PERF_CAPABILITIES 0x345
|
||||
@@ -300,7 +305,9 @@ typedef enum {
|
||||
#define MSR_K7_HWCR_SSEDIS 0x00008000ULL // Disable SSE bit
|
||||
#define MSR_K7_HWCR_MONMWAITUSEREN 0x00000400ULL // Enable MONITOR/MWAIT CPL>0
|
||||
#define MSR_K7_HWCR_TLBFFDIS 0x00000040ULL // Disable TLB Flush Filter
|
||||
#ifndef MSR_K7_HWCR_SMMLOCK
|
||||
#define MSR_K7_HWCR_SMMLOCK 0x00000001ULL // Lock SMM environment
|
||||
#endif
|
||||
|
||||
#ifndef MSR_K8_SYSCFG
|
||||
#define MSR_K8_SYSCFG 0xc0010010
|
||||
@@ -342,6 +349,8 @@ typedef enum {
|
||||
#define MSR_VM_CR_SVME_DISABLE 0x0000000000000010ULL
|
||||
#define MSR_VM_CR_RESERVED 0xffffffffffffffe0ULL
|
||||
|
||||
#define MSR_AMD_DE_CFG 0xc0011029 // Decode configuration
|
||||
#define MSR_AMD_DE_CFG_BIT1 (1ULL<<1)
|
||||
|
||||
/* Syscall/Sysret related MSRs (x86_64) */
|
||||
#define MSR_STAR 0xc0000081 // Also present on Athlons.
|
||||
@@ -475,7 +484,11 @@ typedef enum {
|
||||
/*
|
||||
* MISC_FEATURES_ENABLES bits
|
||||
*/
|
||||
#ifdef MSR_MISC_FEATURES_ENABLES_CPUID_FAULT
|
||||
#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULTING MSR_MISC_FEATURES_ENABLES_CPUID_FAULT
|
||||
#else
|
||||
#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULTING 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
+18
-22
@@ -21,6 +21,7 @@
|
||||
|
||||
#define EXPORT_SYMTAB
|
||||
|
||||
#include "compat_timer.h"
|
||||
#include <linux/file.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/poll.h>
|
||||
@@ -80,6 +81,9 @@ static Bool LinuxDriverCheckPadding(void);
|
||||
|
||||
struct VMXLinuxState linuxState;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
|
||||
typedef int vm_fault_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -105,9 +109,9 @@ long LinuxDriver_Ioctl(struct file *filp, u_int iocmd,
|
||||
static int LinuxDriver_Close(struct inode *inode, struct file *filp);
|
||||
static unsigned int LinuxDriverPoll(struct file *file, poll_table *wait);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
static int LinuxDriverFault(struct vm_fault *fault);
|
||||
static vm_fault_t LinuxDriverFault(struct vm_fault *fault);
|
||||
#elif defined(VMW_NOPAGE_2624)
|
||||
static int LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault);
|
||||
static vm_fault_t LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault);
|
||||
#else
|
||||
static struct page *LinuxDriverNoPage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
@@ -115,7 +119,7 @@ static struct page *LinuxDriverNoPage(struct vm_area_struct *vma,
|
||||
#endif
|
||||
static int LinuxDriverMmap(struct file *filp, struct vm_area_struct *vma);
|
||||
|
||||
static void LinuxDriverPollTimeout(unsigned long clientData);
|
||||
static void LinuxDriverPollTimeout(compat_timer_arg_t unused);
|
||||
static unsigned int LinuxDriverEstimateTSCkHz(void);
|
||||
|
||||
static struct vm_operations_struct vmuser_mops = {
|
||||
@@ -227,7 +231,7 @@ LinuxDriverEstimateTSCkHz(void)
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
LinuxDriverEstimateTSCkHzDeferred(unsigned long data)
|
||||
LinuxDriverEstimateTSCkHzDeferred(compat_timer_arg_t unused)
|
||||
{
|
||||
LinuxDriverEstimateTSCkHz();
|
||||
}
|
||||
@@ -265,9 +269,7 @@ LinuxDriverInitTSCkHz(void)
|
||||
}
|
||||
|
||||
Vmx86_ReadTSCAndUptime(&tsckHzStartTime);
|
||||
tscTimer.function = LinuxDriverEstimateTSCkHzDeferred;
|
||||
tscTimer.expires = jiffies + 4 * HZ;
|
||||
tscTimer.data = 0;
|
||||
add_timer(&tscTimer);
|
||||
}
|
||||
|
||||
@@ -309,9 +311,7 @@ init_module(void)
|
||||
*/
|
||||
|
||||
init_waitqueue_head(&linuxState.pollQueue);
|
||||
init_timer(&linuxState.pollTimer);
|
||||
linuxState.pollTimer.data = 0;
|
||||
linuxState.pollTimer.function = LinuxDriverPollTimeout;
|
||||
compat_timer_setup(&linuxState.pollTimer, LinuxDriverPollTimeout, 0);
|
||||
|
||||
linuxState.fastClockThread = NULL;
|
||||
linuxState.fastClockFile = NULL;
|
||||
@@ -360,7 +360,7 @@ init_module(void)
|
||||
linuxState.deviceName, linuxState.major, linuxState.minor);
|
||||
|
||||
HostIF_InitUptime();
|
||||
init_timer(&tscTimer);
|
||||
compat_timer_setup(&tscTimer, LinuxDriverEstimateTSCkHzDeferred, 0);
|
||||
LinuxDriverInitTSCkHz();
|
||||
Vmx86_InitIDList();
|
||||
|
||||
@@ -741,14 +741,12 @@ void
|
||||
LinuxDriverWakeUp(Bool selective) // IN:
|
||||
{
|
||||
if (selective && linuxState.pollList != NULL) {
|
||||
struct timeval tv;
|
||||
VmTimeType now;
|
||||
VMLinux *p;
|
||||
VMLinux *next;
|
||||
|
||||
HostIF_PollListLock(1);
|
||||
do_gettimeofday(&tv);
|
||||
now = tv.tv_sec * 1000000ULL + tv.tv_usec;
|
||||
now = ktime_get_ns() / NSEC_PER_USEC;
|
||||
|
||||
for (p = linuxState.pollList; p != NULL; p = next) {
|
||||
next = p->pollForw;
|
||||
@@ -815,12 +813,10 @@ LinuxDriverPoll(struct file *filp, // IN:
|
||||
}
|
||||
} else {
|
||||
if (linuxState.fastClockThread && vmLinux->pollTimeoutPtr != NULL) {
|
||||
struct timeval tv;
|
||||
u64 now = ktime_get_ns() / NSEC_PER_USEC;
|
||||
|
||||
do_gettimeofday(&tv);
|
||||
poll_wait(filp, &vmLinux->pollQueue, wait);
|
||||
vmLinux->pollTime = *vmLinux->pollTimeoutPtr +
|
||||
tv.tv_sec * 1000000ULL + tv.tv_usec;
|
||||
vmLinux->pollTime = *vmLinux->pollTimeoutPtr + now;
|
||||
if (vmLinux->pollBack == NULL) {
|
||||
HostIF_PollListLock(2);
|
||||
if (vmLinux->pollBack == NULL) {
|
||||
@@ -858,7 +854,7 @@ LinuxDriverPoll(struct file *filp, // IN:
|
||||
*/
|
||||
|
||||
static void
|
||||
LinuxDriverPollTimeout(unsigned long clientData) // IN:
|
||||
LinuxDriverPollTimeout(compat_timer_arg_t unused) // IN:
|
||||
{
|
||||
LinuxDriverWakeUp(FALSE);
|
||||
}
|
||||
@@ -884,11 +880,11 @@ LinuxDriverPollTimeout(unsigned long clientData) // IN:
|
||||
*/
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
static int
|
||||
static vm_fault_t
|
||||
LinuxDriverFault(struct vm_fault *fault) //IN/OUT
|
||||
#elif defined(VMW_NOPAGE_2624)
|
||||
static int LinuxDriverFault(struct vm_area_struct *vma, //IN
|
||||
struct vm_fault *fault) //IN/OUT
|
||||
static vm_fault_t LinuxDriverFault(struct vm_area_struct *vma, //IN
|
||||
struct vm_fault *fault) //IN/OUT
|
||||
#else
|
||||
static struct page *LinuxDriverNoPage(struct vm_area_struct *vma, //IN
|
||||
unsigned long address, //IN
|
||||
@@ -1287,7 +1283,7 @@ LinuxDriverReadTSC(void *data, // OUT: TSC values
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
__attribute__((always_inline)) static Bool
|
||||
__always_inline static Bool
|
||||
LinuxDriverSyncReadTSCs(uint64 *delta) // OUT: TSC max - TSC min
|
||||
{
|
||||
TSCDelta tscDelta;
|
||||
|
||||
+101
-191
@@ -30,6 +30,7 @@
|
||||
|
||||
/* Must come before vmware.h --hpreg */
|
||||
#include "compat_page.h"
|
||||
#include "compat_timer.h"
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/file.h>
|
||||
@@ -68,7 +69,10 @@
|
||||
#endif
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/irq_vectors.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/kthread.h>
|
||||
@@ -98,6 +102,41 @@
|
||||
#include "pgtbl.h"
|
||||
#include "vmmonInt.h"
|
||||
#include "versioned_atomic.h"
|
||||
#include "compat_poll.h"
|
||||
#include "compat_mmap_lock.h"
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
# define global_zone_page_state global_page_state
|
||||
#endif
|
||||
|
||||
static unsigned long get_nr_slab_unreclaimable(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
||||
return global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
|
||||
return global_node_page_state(NR_SLAB_UNRECLAIMABLE);
|
||||
#else
|
||||
return global_page_state(NR_SLAB_UNRECLAIMABLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned long get_nr_unevictable(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
|
||||
return global_node_page_state(NR_UNEVICTABLE);
|
||||
#else
|
||||
return global_page_state(NR_UNEVICTABLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned long get_nr_anon_mapped(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
|
||||
return global_node_page_state(NR_ANON_MAPPED);
|
||||
#else
|
||||
return global_page_state(NR_ANON_PAGES);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if we can use high resolution timers.
|
||||
@@ -142,13 +181,7 @@ static DECLARE_TASKLET(timerTasklet, HostIFWakeupClockThread, 0);
|
||||
*/
|
||||
#define LOCKED_PAGE_SLACK 10000
|
||||
|
||||
static struct {
|
||||
Atomic_uint64 uptimeBase;
|
||||
VersionedAtomic version;
|
||||
uint64 monotimeBase;
|
||||
unsigned long jiffiesBase;
|
||||
struct timer_list timer;
|
||||
} uptimeState;
|
||||
u64 uptime_base;
|
||||
|
||||
/*
|
||||
* First Page Locking strategy
|
||||
@@ -207,6 +240,21 @@ static struct {
|
||||
uint8 monitorIPIVector;
|
||||
uint8 hvIPIVector;
|
||||
|
||||
static unsigned long compat_totalram_pages(void)
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
|
||||
return totalram_pages;
|
||||
#else
|
||||
return totalram_pages();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) && defined(VERIFY_WRITE)
|
||||
#define write_access_ok(addr, size) access_ok(VERIFY_WRITE, addr, size)
|
||||
#else
|
||||
#define write_access_ok(addr, size) access_ok(addr, size)
|
||||
#endif
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
@@ -695,7 +743,24 @@ HostIF_PollListUnlock(int callerID) // IN
|
||||
static void *
|
||||
MapCrossPage(struct page *p) // IN:
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
|
||||
return vmap(&p, 1, VM_MAP, VM_PAGE_KERNEL_EXEC);
|
||||
#else
|
||||
/* Starting with 5.8, vmap() always sets the NX bit, but the cross
|
||||
* page needs to be executable. */
|
||||
pte_t *ptes[1];
|
||||
struct vm_struct *area = alloc_vm_area(1UL << PAGE_SHIFT, ptes);
|
||||
if (area == NULL)
|
||||
return NULL;
|
||||
|
||||
set_pte(ptes[0], mk_pte(p, VM_PAGE_KERNEL_EXEC));
|
||||
|
||||
preempt_disable();
|
||||
__flush_tlb_all();
|
||||
preempt_enable();
|
||||
|
||||
return area->addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1164,7 +1229,7 @@ HostIFGetUserPages(void *uvAddr, // IN
|
||||
{
|
||||
int retval;
|
||||
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
mmap_read_lock(current->mm);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
|
||||
retval = get_user_pages((unsigned long)uvAddr, numPages, 0, ppages, NULL);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
|
||||
@@ -1173,7 +1238,7 @@ HostIFGetUserPages(void *uvAddr, // IN
|
||||
retval = get_user_pages(current, current->mm, (unsigned long)uvAddr,
|
||||
numPages, 0, 0, ppages, NULL);
|
||||
#endif
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
mmap_read_unlock(current->mm);
|
||||
|
||||
return retval != numPages;
|
||||
}
|
||||
@@ -1569,14 +1634,7 @@ unsigned int
|
||||
HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN
|
||||
unsigned int currentlyLockedPages) // IN
|
||||
{
|
||||
/*
|
||||
* This variable is available and exported to modules,
|
||||
* since at least 2.6.0.
|
||||
*/
|
||||
|
||||
extern unsigned long totalram_pages;
|
||||
|
||||
unsigned int totalPhysicalPages = totalram_pages;
|
||||
unsigned int totalPhysicalPages = compat_totalram_pages();
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
|
||||
return MemDefaults_CalcMaxLockedPages(totalPhysicalPages);
|
||||
@@ -1594,16 +1652,11 @@ HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN
|
||||
unsigned int reservedPages = MEMDEFAULTS_MIN_HOST_PAGES;
|
||||
unsigned int hugePages = (vm == NULL) ? 0 :
|
||||
BYTES_2_PAGES(vm->memInfo.hugePageBytes);
|
||||
unsigned int lockedPages = global_page_state(NR_PAGETABLE) +
|
||||
global_page_state(NR_SLAB_UNRECLAIMABLE) +
|
||||
global_page_state(NR_UNEVICTABLE) +
|
||||
unsigned int lockedPages = global_zone_page_state(NR_PAGETABLE) +
|
||||
get_nr_slab_unreclaimable() +
|
||||
get_nr_unevictable() +
|
||||
hugePages + reservedPages;
|
||||
unsigned int anonPages =
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
|
||||
global_page_state(NR_ANON_MAPPED);
|
||||
#else
|
||||
global_page_state(NR_ANON_PAGES);
|
||||
#endif
|
||||
unsigned int anonPages = get_nr_anon_mapped();
|
||||
unsigned int swapPages = BYTES_2_PAGES(linuxState.swapSize);
|
||||
|
||||
if (anonPages > swapPages) {
|
||||
@@ -1661,146 +1714,6 @@ HostIF_WaitForFreePages(unsigned int timeoutMs) // IN:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* HostIFReadUptimeWork --
|
||||
*
|
||||
* Reads the current uptime. The uptime is based on getimeofday,
|
||||
* which provides the needed high resolution. However, we don't
|
||||
* want uptime to be warped by e.g. calls to settimeofday. So, we
|
||||
* use a jiffies based monotonic clock to sanity check the uptime.
|
||||
* If the uptime is more than one second from the monotonic time,
|
||||
* we assume that the time of day has been set, and recalculate the
|
||||
* uptime base to get uptime back on track with monotonic time. On
|
||||
* the other hand, we do expect jiffies based monotonic time and
|
||||
* timeofday to have small drift (due to NTP rate correction, etc).
|
||||
* We handle this by rebasing the jiffies based monotonic clock
|
||||
* every second (see HostIFUptimeResyncMono).
|
||||
*
|
||||
* Results:
|
||||
* The uptime, in units of UPTIME_FREQ. Also returns the jiffies
|
||||
* value that was used in the monotonic time calculation.
|
||||
*
|
||||
* Side effects:
|
||||
* May reset the uptime base in the case gettimeofday warp was
|
||||
* detected.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static uint64
|
||||
HostIFReadUptimeWork(unsigned long *j) // OUT: current jiffies
|
||||
{
|
||||
struct timeval tv;
|
||||
uint64 monotime, uptime, upBase, monoBase;
|
||||
int64 diff;
|
||||
uint32 version;
|
||||
unsigned long jifs, jifBase;
|
||||
unsigned int attempts = 0;
|
||||
|
||||
/* Assert that HostIF_InitUptime has been called. */
|
||||
ASSERT(uptimeState.timer.function);
|
||||
|
||||
retry:
|
||||
do {
|
||||
version = VersionedAtomic_BeginTryRead(&uptimeState.version);
|
||||
jifs = jiffies;
|
||||
jifBase = uptimeState.jiffiesBase;
|
||||
monoBase = uptimeState.monotimeBase;
|
||||
} while (!VersionedAtomic_EndTryRead(&uptimeState.version, version));
|
||||
|
||||
do_gettimeofday(&tv);
|
||||
upBase = Atomic_Read64(&uptimeState.uptimeBase);
|
||||
|
||||
monotime = (uint64)(jifs - jifBase) * (UPTIME_FREQ / HZ);
|
||||
monotime += monoBase;
|
||||
|
||||
uptime = tv.tv_usec * (UPTIME_FREQ / 1000000) + tv.tv_sec * UPTIME_FREQ;
|
||||
uptime += upBase;
|
||||
|
||||
/*
|
||||
* Use the jiffies based monotonic time to sanity check gettimeofday.
|
||||
* If they differ by more than one second, assume the time of day has
|
||||
* been warped, and use the jiffies time to undo (most of) the warp.
|
||||
*/
|
||||
|
||||
diff = uptime - monotime;
|
||||
if (UNLIKELY(diff < -UPTIME_FREQ || diff > UPTIME_FREQ)) {
|
||||
/* Compute a new uptimeBase to get uptime back on track. */
|
||||
uint64 newUpBase = monotime - (uptime - upBase);
|
||||
|
||||
attempts++;
|
||||
if (!Atomic_CMPXCHG64(&uptimeState.uptimeBase, &upBase, &newUpBase) &&
|
||||
attempts < 5) {
|
||||
/* Another thread updated uptimeBase. Recalculate uptime. */
|
||||
goto retry;
|
||||
}
|
||||
uptime = monotime;
|
||||
|
||||
Log("%s: detected settimeofday: fixed uptimeBase old %"FMT64"u "
|
||||
"new %"FMT64"u attempts %u\n", __func__,
|
||||
upBase, newUpBase, attempts);
|
||||
}
|
||||
*j = jifs;
|
||||
|
||||
return uptime;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* HostIFUptimeResyncMono --
|
||||
*
|
||||
* Timer that fires ever second to resynchronize the jiffies based
|
||||
* monotonic time with the uptime.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Resets the monotonic time bases so that jiffies based monotonic
|
||||
* time does not drift from gettimeofday over the long term.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
HostIFUptimeResyncMono(unsigned long data) // IN: ignored
|
||||
{
|
||||
unsigned long jifs;
|
||||
uintptr_t flags;
|
||||
|
||||
/*
|
||||
* Read the uptime and the corresponding jiffies value. This will
|
||||
* also correct the uptime (which is based on time of day) if needed
|
||||
* before we rebase monotonic time (which is based on jiffies).
|
||||
*/
|
||||
|
||||
uint64 uptime = HostIFReadUptimeWork(&jifs);
|
||||
|
||||
/*
|
||||
* Every second, recalculate monoBase and jiffiesBase to squash small
|
||||
* drift between gettimeofday and jiffies. Also, this prevents
|
||||
* (jiffies - jiffiesBase) wrap on 32-bits.
|
||||
*/
|
||||
|
||||
SAVE_FLAGS(flags);
|
||||
CLEAR_INTERRUPTS();
|
||||
VersionedAtomic_BeginWrite(&uptimeState.version);
|
||||
|
||||
uptimeState.monotimeBase = uptime;
|
||||
uptimeState.jiffiesBase = jifs;
|
||||
|
||||
VersionedAtomic_EndWrite(&uptimeState.version);
|
||||
RESTORE_FLAGS(flags);
|
||||
|
||||
/* Reschedule this timer to expire in one second. */
|
||||
mod_timer(&uptimeState.timer, jifs + HZ);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1812,8 +1725,7 @@ HostIFUptimeResyncMono(unsigned long data) // IN: ignored
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Sets the initial values for the uptime state, and schedules
|
||||
* the uptime timer.
|
||||
* Sets the initial value for the uptime base.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1821,17 +1733,7 @@ HostIFUptimeResyncMono(unsigned long data) // IN: ignored
|
||||
void
|
||||
HostIF_InitUptime(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
uptimeState.jiffiesBase = jiffies;
|
||||
do_gettimeofday(&tv);
|
||||
Atomic_Write64(&uptimeState.uptimeBase,
|
||||
-(tv.tv_usec * (UPTIME_FREQ / 1000000) +
|
||||
tv.tv_sec * UPTIME_FREQ));
|
||||
|
||||
init_timer(&uptimeState.timer);
|
||||
uptimeState.timer.function = HostIFUptimeResyncMono;
|
||||
mod_timer(&uptimeState.timer, jiffies + HZ);
|
||||
uptime_base = ktime_get_ns();
|
||||
}
|
||||
|
||||
|
||||
@@ -1840,13 +1742,13 @@ HostIF_InitUptime(void)
|
||||
*
|
||||
* HostIF_CleanupUptime --
|
||||
*
|
||||
* Cleanup uptime state, called at module unloading time.
|
||||
* No-op, left for backward compatibility.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Deschedule the uptime timer.
|
||||
* None
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1854,7 +1756,6 @@ HostIF_InitUptime(void)
|
||||
void
|
||||
HostIF_CleanupUptime(void)
|
||||
{
|
||||
del_timer_sync(&uptimeState.timer);
|
||||
}
|
||||
|
||||
|
||||
@@ -1878,9 +1779,10 @@ HostIF_CleanupUptime(void)
|
||||
uint64
|
||||
HostIF_ReadUptime(void)
|
||||
{
|
||||
unsigned long jifs;
|
||||
u64 tm;
|
||||
|
||||
return HostIFReadUptimeWork(&jifs);
|
||||
tm = ktime_get_ns();
|
||||
return (tm - uptime_base) / (NSEC_PER_SEC / UPTIME_FREQ);
|
||||
}
|
||||
|
||||
|
||||
@@ -2251,7 +2153,7 @@ isVAReadable(VA r) // IN:
|
||||
int ret;
|
||||
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
set_fs(KERNEL_DS);
|
||||
r = APICR_TO_ADDR(r, APICR_VERSION);
|
||||
ret = HostIF_CopyFromUser(&dummy, (void*)r, sizeof(dummy));
|
||||
set_fs(old_fs);
|
||||
@@ -2284,7 +2186,7 @@ SetVMAPICAddr(VMDriver *vm, // IN/OUT: driver state
|
||||
volatile void *hostapic;
|
||||
|
||||
ASSERT_ON_COMPILE(APICR_SIZE <= PAGE_SIZE);
|
||||
hostapic = (volatile void *) ioremap_nocache(ma, PAGE_SIZE);
|
||||
hostapic = (volatile void *) ioremap(ma, PAGE_SIZE);
|
||||
if (hostapic) {
|
||||
if ((APIC_VERSIONREG(hostapic) & 0xF0) == 0x10) {
|
||||
vm->hostAPIC.base = (volatile uint32 (*)[4]) hostapic;
|
||||
@@ -2452,7 +2354,7 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
|
||||
}
|
||||
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
set_fs(KERNEL_DS);
|
||||
|
||||
{
|
||||
struct poll_wqueues table;
|
||||
@@ -2460,7 +2362,7 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
|
||||
|
||||
poll_initwait(&table);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
mask = file->f_op->poll(file, &table.pt);
|
||||
mask = compat_vfs_poll(file, &table.pt);
|
||||
if (!(mask & (POLLIN | POLLERR | POLLHUP))) {
|
||||
vm->vmhost->vcpuSemaTask[vcpuid] = current;
|
||||
schedule_timeout(timeoutms * HZ / 1000); // convert to Hz
|
||||
@@ -2476,7 +2378,11 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
|
||||
* reading no bytes (EAGAIN - non blocking fd) or sizeof(uint64).
|
||||
*/
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
res = kernel_read(file, (char *) &value, sizeof value, &file->f_pos);
|
||||
#else
|
||||
res = file->f_op->read(file, (char *) &value, sizeof value, &file->f_pos);
|
||||
#endif
|
||||
|
||||
if (res == sizeof value) {
|
||||
res = MX_WAITNORMAL;
|
||||
@@ -2581,7 +2487,7 @@ HostIF_SemaphoreSignal(uint64 *args) // IN:
|
||||
}
|
||||
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
set_fs(KERNEL_DS);
|
||||
|
||||
/*
|
||||
* Always write sizeof(uint64) bytes. This works fine for eventfd and
|
||||
@@ -2589,7 +2495,11 @@ HostIF_SemaphoreSignal(uint64 *args) // IN:
|
||||
* it be present.
|
||||
*/
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
res = kernel_write(file, (char *) &value, sizeof value, &file->f_pos);
|
||||
#else
|
||||
res = file->f_op->write(file, (char *) &value, sizeof value, &file->f_pos);
|
||||
#endif
|
||||
|
||||
if (res == sizeof value) {
|
||||
res = MX_WAITNORMAL;
|
||||
@@ -3524,7 +3434,7 @@ HostIF_SetFastClockRate(unsigned int rate) // IN: Frequency in Hz.
|
||||
}
|
||||
} else {
|
||||
if (linuxState.fastClockThread) {
|
||||
force_sig(SIGKILL, linuxState.fastClockThread);
|
||||
send_sig(SIGKILL, linuxState.fastClockThread, 1);
|
||||
kthread_stop(linuxState.fastClockThread);
|
||||
close_rtc(linuxState.fastClockFile, current->files);
|
||||
|
||||
@@ -3572,7 +3482,7 @@ HostIF_MapUserMem(VA addr, // IN: User memory virtual address
|
||||
|
||||
ASSERT(handle);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, p, size)) {
|
||||
if (!write_access_ok(p, size)) {
|
||||
printk(KERN_ERR "%s: Couldn't verify write to uva 0x%p with size %"
|
||||
FMTSZ"u\n", __func__, p, size);
|
||||
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ prebuild:: ;
|
||||
postbuild:: ;
|
||||
|
||||
$(DRIVER_KO): prebuild
|
||||
$(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
|
||||
$(MAKE) -C $(BUILD_DIR) M=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
|
||||
MODULEBUILDDIR=$(MODULEBUILDDIR) modules
|
||||
$(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \
|
||||
MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild
|
||||
|
||||
@@ -35,6 +35,6 @@ $(DRIVER)-y := driver.o hub.o userif.o netif.o bridge.o procfs.o smac_compat.o \
|
||||
####
|
||||
|
||||
clean:
|
||||
rm -rf $(DRIVER).o $(DRIVER).mod.o $(DRIVER).mod.c $(DRIVER).ko \
|
||||
rm -rf $(DRIVER).o $(DRIVER).mod.o $(DRIVER).mod.c $(DRIVER).ko .cache.mk \
|
||||
.tmp_versions Module.symvers Modules.symvers Module.markers \
|
||||
modules.order $($(DRIVER)-y) .*.cmd .*.o.flags
|
||||
+7
-8
@@ -65,7 +65,7 @@
|
||||
#endif
|
||||
|
||||
#if LOGLEVEL >= 4
|
||||
static struct timeval vnetTime;
|
||||
static u64 vnetTime;
|
||||
#endif
|
||||
|
||||
typedef struct VNetBridge VNetBridge;
|
||||
@@ -636,7 +636,7 @@ VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
atomic_inc(&clone->users);
|
||||
clone = skb_get(clone);
|
||||
|
||||
clone->dev = dev;
|
||||
clone->protocol = eth_type_trans(clone, dev);
|
||||
@@ -696,7 +696,7 @@ VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack
|
||||
|
||||
netif_rx_ni(clone);
|
||||
# if LOGLEVEL >= 4
|
||||
do_gettimeofday(&vnetTime);
|
||||
vnetTime = ktime_get_ns();
|
||||
# endif
|
||||
}
|
||||
}
|
||||
@@ -1661,12 +1661,11 @@ VNetBridgeReceiveFromDev(struct sk_buff *skb, // IN: packet to receive
|
||||
|
||||
# if LOGLEVEL >= 4
|
||||
{
|
||||
struct timeval now;
|
||||
do_gettimeofday(&now);
|
||||
u64 now;
|
||||
|
||||
now = ktime_get_ns();
|
||||
LOG(3, (KERN_DEBUG "bridge-%s: time %d\n",
|
||||
bridge->name,
|
||||
(int)((now.tv_sec * 1000000 + now.tv_usec)
|
||||
- (vnetTime.tv_sec * 1000000 + vnetTime.tv_usec))));
|
||||
bridge->name, (int)((now - vnetTime) / NSEC_PER_USEC)));
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef __COMPAT_MMAP_LOCK_H__
|
||||
#define __COMPAT_MMAP_LOCK_H__
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
* In 5.8-rc1, mmap locking was reworked to use wrappers around mmap_sem
|
||||
* (which was also renamed to mmap_lock). All code is now supposed to use
|
||||
* these wrappers as the internal implementation of the lock may change in
|
||||
* the future.
|
||||
*
|
||||
* Check also _LINUX_MMAP_LOCK_H to handle possible backports to distribution
|
||||
* pre-5.8 kernel. This macro is defined in <linux/mmap_lock.h> which is also
|
||||
* included in <linux/mm.h> since the commit introducing the wrappers so that
|
||||
* we should have it defined in any kernel providing the new API.
|
||||
*/
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) || defined(_LINUX_MMAP_LOCK_H)
|
||||
#include <linux/mmap_lock.h>
|
||||
#else
|
||||
|
||||
static inline void mmap_read_lock(struct mm_struct *mm)
|
||||
{
|
||||
down_read(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
static inline void mmap_read_unlock(struct mm_struct *mm)
|
||||
{
|
||||
up_read(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
#endif /* 5.8.0 */
|
||||
|
||||
#endif /* __COMPAT_MMAP_LOCK_H__ */
|
||||
@@ -337,7 +337,8 @@ typedef netdev_features_t compat_netdev_features_t;
|
||||
typedef u32 compat_netdev_features_t;
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) || \
|
||||
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= 0x0704)
|
||||
#define compat_netif_trans_update(d) netif_trans_update(d)
|
||||
#else
|
||||
#define compat_netif_trans_update(d) do { (d)->trans_start = jiffies; } while (0)
|
||||
|
||||
@@ -161,6 +161,14 @@ VNetProcOpen(struct inode *inode, // IN:
|
||||
}
|
||||
|
||||
/* Our procfs callbacks. We only need to specialize open. */
|
||||
#ifdef DEFINE_PROC_SHOW_ATTRIBUTE
|
||||
static const struct proc_ops fops = {
|
||||
.proc_open = VNetProcOpen,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
#else
|
||||
static struct file_operations fops = {
|
||||
.open = VNetProcOpen,
|
||||
.read = seq_read,
|
||||
@@ -168,6 +176,7 @@ static struct file_operations fops = {
|
||||
.release = single_release,
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+41
-13
@@ -47,6 +47,7 @@
|
||||
|
||||
#include "vnetInt.h"
|
||||
#include "compat_skbuff.h"
|
||||
#include "compat_mmap_lock.h"
|
||||
#include "vmnetInt.h"
|
||||
#include "vm_atomic.h"
|
||||
#include "vm_assert.h"
|
||||
@@ -84,11 +85,37 @@ static int VNetUserIfSetUplinkState(VNetPort *port, uint8 linkUp);
|
||||
extern unsigned int vnet_max_qlen;
|
||||
|
||||
#if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
|
||||
# define compat_kmap(page) kmap(page)
|
||||
# define compat_kunmap(page) kunmap(page)
|
||||
# define compat_kmap_frag(frag) kmap((frag)->page)
|
||||
# define compat_kunmap_frag(page) kunmap((frag)->page)
|
||||
#else
|
||||
# define compat_kmap(page) kmap((page).p)
|
||||
# define compat_kunmap(page) kunmap((page).p)
|
||||
# define compat_kmap_frag(frag) kmap(skb_frag_page(frag))
|
||||
# define compat_kunmap_frag(frag) kunmap(skb_frag_page(frag))
|
||||
#endif
|
||||
|
||||
static unsigned int compat_skb_frag_size(const skb_frag_t *frag)
|
||||
{
|
||||
#if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
|
||||
return frag->size;
|
||||
#else
|
||||
return skb_frag_size(frag);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned int compat_skb_frag_off(const skb_frag_t *frag)
|
||||
{
|
||||
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 4, 0) && \
|
||||
!(defined(CONFIG_SUSE_VERSION) && CONFIG_SUSE_VERSION == 15 && \
|
||||
defined(CONFIG_SUSE_PATCHLEVEL) && CONFIG_SUSE_PATCHLEVEL >= 2)
|
||||
return frag->page_offset;
|
||||
#else
|
||||
return skb_frag_off(frag);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) && defined(VERIFY_WRITE)
|
||||
#define write_access_ok(addr, size) access_ok(VERIFY_WRITE, addr, size)
|
||||
#else
|
||||
#define write_access_ok(addr, size) access_ok(addr, size)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -115,7 +142,7 @@ UserifLockPage(VA addr) // IN
|
||||
struct page *page = NULL;
|
||||
int retval;
|
||||
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
mmap_read_lock(current->mm);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
|
||||
retval = get_user_pages(addr, 1, FOLL_WRITE, &page, NULL);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
|
||||
@@ -124,7 +151,7 @@ UserifLockPage(VA addr) // IN
|
||||
retval = get_user_pages(current, current->mm, addr,
|
||||
1, 1, 0, &page, NULL);
|
||||
#endif
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
mmap_read_unlock(current->mm);
|
||||
|
||||
if (retval != 1) {
|
||||
return NULL;
|
||||
@@ -157,7 +184,7 @@ VNetUserIfMapPtr(VA uAddr, // IN: pointer to user memory
|
||||
struct page **p, // OUT: locked page
|
||||
void **ptr) // OUT: kernel mapped pointer
|
||||
{
|
||||
if (!access_ok(VERIFY_WRITE, (void *)uAddr, size) ||
|
||||
if (!write_access_ok((void *)uAddr, size) ||
|
||||
(((uAddr + size - 1) & ~(PAGE_SIZE - 1)) !=
|
||||
(uAddr & ~(PAGE_SIZE - 1)))) {
|
||||
return -EINVAL;
|
||||
@@ -594,20 +621,21 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy
|
||||
for (frag = skb_shinfo(skb)->frags;
|
||||
frag != skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags;
|
||||
frag++) {
|
||||
if (frag->size > 0) {
|
||||
if (compat_skb_frag_size(frag) > 0) {
|
||||
unsigned int tmpCsum;
|
||||
const void *vaddr;
|
||||
|
||||
vaddr = compat_kmap(frag->page);
|
||||
tmpCsum = csum_and_copy_to_user(vaddr + frag->page_offset,
|
||||
curr, frag->size, 0, &err);
|
||||
compat_kunmap(frag->page);
|
||||
vaddr = compat_kmap_frag(frag);
|
||||
tmpCsum = csum_and_copy_to_user(vaddr + compat_skb_frag_off(frag),
|
||||
curr, compat_skb_frag_size(frag), 0,
|
||||
&err);
|
||||
compat_kunmap_frag(frag);
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
csum = csum_block_add(csum, tmpCsum, curr - buf);
|
||||
curr += frag->size;
|
||||
curr += compat_skb_frag_size(frag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <linux/pci_ids.h>
|
||||
|
||||
/* LSILogic 53C1030 Parallel SCSI controller
|
||||
* LSILogic SAS1068 SAS controller
|
||||
*/
|
||||
@@ -53,7 +55,10 @@
|
||||
* VMware HD Audio codec
|
||||
* VMware HD Audio controller
|
||||
*/
|
||||
#ifndef PCI_VENDOR_ID_VMWARE
|
||||
#define PCI_VENDOR_ID_VMWARE 0x15AD
|
||||
#endif
|
||||
|
||||
#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
|
||||
#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
|
||||
#define PCI_DEVICE_ID_VMWARE_VGA 0x0711
|
||||
@@ -70,7 +75,11 @@
|
||||
#define PCI_DEVICE_ID_VMWARE_1394 0x0780
|
||||
#define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790
|
||||
#define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VMWARE_VMXNET3
|
||||
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
|
||||
#endif
|
||||
|
||||
#define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0
|
||||
#define PCI_DEVICE_ID_VMWARE_82574 0x07D0
|
||||
#define PCI_DEVICE_ID_VMWARE_AHCI 0x07E0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 1998 VMware, Inc. All rights reserved.
|
||||
* Copyright (C) 1998, 2017 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
|
||||
extern struct proto vmnet_proto;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) || defined(sk_net_refcnt)
|
||||
# define compat_sk_alloc(_bri, _pri) sk_alloc(&init_net, \
|
||||
PF_NETLINK, _pri, &vmnet_proto, 1)
|
||||
#elif defined(VMW_NETDEV_HAS_NET)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2002-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation version 2 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* vmware_pack_begin.h --
|
||||
*
|
||||
* Begin of structure packing. See vmware_pack_init.h for details.
|
||||
*
|
||||
* Note that we do not use the following construct in this include file,
|
||||
* because we want to emit the code every time the file is included --hpreg
|
||||
*
|
||||
* #ifndef foo
|
||||
* # define foo
|
||||
* ...
|
||||
* #endif
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "vmware_pack_init.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma pack(push, 1)
|
||||
#elif __GNUC__
|
||||
#else
|
||||
# error Compiler packing...
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2002-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation version 2 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
/*
|
||||
* vmware_pack_end.h --
|
||||
*
|
||||
* End of structure packing. See vmware_pack_init.h for details.
|
||||
*
|
||||
* Note that we do not use the following construct in this include file,
|
||||
* because we want to emit the code every time the file is included --hpreg
|
||||
*
|
||||
* #ifndef foo
|
||||
* # define foo
|
||||
* ...
|
||||
* #endif
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "vmware_pack_init.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma pack(pop)
|
||||
#elif __GNUC__
|
||||
__attribute__((__packed__))
|
||||
#else
|
||||
# error Compiler packing...
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
/*********************************************************
|
||||
* Copyright (C) 2002-2015 VMware, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation version 2 and no later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
#ifndef __VMWARE_PACK_INIT_H__
|
||||
# define __VMWARE_PACK_INIT_H__
|
||||
|
||||
|
||||
/*
|
||||
* vmware_pack_init.h --
|
||||
*
|
||||
* Platform-independent code to make the compiler pack (i.e. have them
|
||||
* occupy the smallest possible space) structure definitions. The following
|
||||
* constructs are known to work --hpreg
|
||||
*
|
||||
* #include "vmware_pack_begin.h"
|
||||
* struct foo {
|
||||
* ...
|
||||
* }
|
||||
* #include "vmware_pack_end.h"
|
||||
* ;
|
||||
*
|
||||
* typedef
|
||||
* #include "vmware_pack_begin.h"
|
||||
* struct foo {
|
||||
* ...
|
||||
* }
|
||||
* #include "vmware_pack_end.h"
|
||||
* foo;
|
||||
*/
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/*
|
||||
* MSVC 6.0 emits warning 4103 when the pack push and pop pragma pairing is
|
||||
* not balanced within 1 included file. That is annoying because our scheme
|
||||
* is based on the pairing being balanced between 2 included files.
|
||||
*
|
||||
* So we disable this warning, but this is safe because the compiler will also
|
||||
* emit warning 4161 when there is more pops than pushes within 1 main
|
||||
* file --hpreg
|
||||
*/
|
||||
|
||||
# pragma warning(disable:4103)
|
||||
#elif __GNUC__
|
||||
#else
|
||||
# error Compiler packing...
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __VMWARE_PACK_INIT_H__ */
|
||||
Whitespace-only changes.
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user