Compare commits

..
28 changed files with 280 additions and 708 deletions

No files matched your search

-2
View File
@@ -3,8 +3,6 @@
*.ko
*.ko.cmd
*.mod.c
*.tar
.tmp_versions
.cache.mk
Module.symvers
modules.order
-197
View File
@@ -1,197 +0,0 @@
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.
-49
View File
@@ -1,49 +0,0 @@
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)
+3 -8
View File
@@ -12,17 +12,12 @@ 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${kver}" marks the set of
changes needed to build modules from Player ${ver} against kernel ${kver},
against recent kernel versions. Tag "p${ver}-k${ver}" marks the set of
changes needed to build modules from Player ${ver} against kernel ${ver},
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 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.
p12.5.5-k4.11 with kernel 4.10) but it's not completely reliable.
This repository is provided "as is" with no guarantees. Use the contents on
your own risk.
+1 -1
View File
@@ -107,7 +107,7 @@ prebuild:: ;
postbuild:: ;
$(DRIVER_KO): prebuild
$(MAKE) -C $(BUILD_DIR) M=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
$(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) modules
$(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild
+1 -1
View File
@@ -31,7 +31,7 @@ $(DRIVER)-y := $(subst $(SRCROOT)/, , $(patsubst %.c, %.o, \
$(SRCROOT)/bootstrap/*.c)))
clean:
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions .cache.mk \
rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \
Module.symvers Modules.symvers Module.markers modules.order \
$(foreach dir,linux/ common/ vmcore/ bootstrap/ \
./,$(addprefix $(dir),.*.cmd .*.o.flags *.o)))
+1 -28
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998, 2016-2018 VMware, Inc. All rights reserved.
* Copyright (C) 1998, 2016-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
@@ -37,7 +37,6 @@
uint32 cpuidFeatures;
static CpuidVendor vendor = CPUID_NUM_VENDORS;
static uint32 version;
static Bool hasSpecCtrl;
/*
@@ -100,9 +99,6 @@ CPUID_Init(void)
Warning("VMMON CPUID: Unrecognized CPU\n");
vendor = CPUID_VENDOR_UNKNOWN;
}
__GET_CPUID2(7, 0, &regs);
hasSpecCtrl = vendor == CPUID_VENDOR_INTEL && ((regs.edx >> 26) & 0x3) != 0;
}
@@ -180,26 +176,3 @@ CPUID_HostSupportsHV(void)
return (vendor == CPUID_VENDOR_AMD && SVM_CapableCPU()) ||
(vendor == CPUID_VENDOR_INTEL && VT_CapableCPU());
}
/*
*-----------------------------------------------------------------------------
*
* 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 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998, 2016-2018 VMware, Inc. All rights reserved.
* Copyright (C) 1998, 2016-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
@@ -38,7 +38,6 @@ CpuidVendor CPUID_GetVendor(void);
uint32 CPUID_GetVersion(void);
Bool CPUID_AddressSizeSupported(void);
Bool CPUID_HostSupportsHV(void);
Bool CPUID_HostSupportsSpecCtrl(void);
static INLINE uint32
CPUID_GetFeatures(void)
+1 -44
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2018 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
@@ -82,9 +82,6 @@
# 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)
@@ -2203,23 +2200,12 @@ 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)
/*
@@ -2385,11 +2371,6 @@ 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);
@@ -2607,14 +2588,6 @@ 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);
@@ -2622,16 +2595,6 @@ 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.
@@ -2769,12 +2732,6 @@ 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
-30
View File
@@ -1,30 +0,0 @@
#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__ */
-1
View File
@@ -251,7 +251,6 @@ 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 */
}
+2 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2018 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
@@ -144,7 +144,7 @@ PtrToVA64(void const *ptr) // IN
*
*/
#define VMMON_VERSION (331 << 16 | 0)
#define VMMON_VERSION (329 << 16 | 0)
#define VMMON_VERSION_MAJOR(v) ((uint32) (v) >> 16)
#define VMMON_VERSION_MINOR(v) ((uint16) (v))
+2 -3
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2018 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
@@ -374,7 +374,6 @@ struct VMCrossPageData {
volatile Bool wsException[NUM_EXCEPTIONS]; // Tracks faults in worldswitch.
uint64 wsUD2; // IP of ud2 instr or 0 if unset.
uint64 specCtrl; /* host MSR_SPEC_CTRL value before world switch. */
}
#include "vmware_pack_end.h"
VMCrossPageData;
@@ -431,7 +430,7 @@ struct VMCrossPage {
#include "vmware_pack_end.h"
VMCrossPage;
#define CROSSPAGE_VERSION_BASE 0xbfc /* increment by 1 */
#define CROSSPAGE_VERSION_BASE 0xbfb /* increment by 1 */
#define CROSSPAGE_VERSION ((CROSSPAGE_VERSION_BASE << 1) + WS_INTR_STRESS)
#if !defined(VMX86_SERVER) && defined(VMM)
+1 -2
View File
@@ -67,7 +67,6 @@ 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) \
@@ -108,7 +107,7 @@ NORETURN void Panic_NoSave(const char *fmt, ...) PRINTF_DECL(1, 2);
} while(0)
#else
#define Panic panic
NORETURN void Panic(const char *fmt, ...) PRINTF_DECL(1, 2);
#endif
void LogThrottled(uint32 *count, const char *fmt, ...) PRINTF_DECL(2, 3);
-4
View File
@@ -35,8 +35,6 @@
#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
@@ -77,9 +75,7 @@
#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
+2 -12
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2018 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
@@ -460,11 +460,6 @@ FLAG( 6, 0, ECX, 0, 1, HW_COORD_FEEDBACK, NO, 0, FALSE) \
FLAG( 6, 0, ECX, 1, 1, ACNT2, ANY, 13, FALSE) \
FLAG( 6, 0, ECX, 3, 1, ENERGY_PERF_BIAS, NO, 0, FALSE)
#define CPUID_7_EDX_28 \
FLAG( 7, 0, EDX, 28, 1, LEVEL7EDX_RSVD1, NO, 0, FALSE)
#define CPUID_7_EDX_31 \
FLAG( 7, 0, EDX, 31, 1, LEVEL7EDX_RSVD2, NO, 0, FALSE)
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV, CPL3 */
#define CPUID_FIELD_DATA_LEVEL_7 \
@@ -504,11 +499,7 @@ FLAG( 7, 0, ECX, 1, 1, AVX512VBMI, YES, 15, TRUE) \
FLAG( 7, 0, ECX, 3, 1, PKU, YES, 13, TRUE) \
FLAG( 7, 0, ECX, 4, 1, OSPKE, ANY, 13, TRUE) \
FLAG( 7, 0, ECX, 30, 1, SGX_LC, NO, 0, FALSE) \
FLAG( 7, 0, EDX, 26, 1, IBRSIBPB, ANY, 9, FALSE) \
FLAG( 7, 0, EDX, 27, 1, STIBP, YES, 9, FALSE) \
CPUID_7_EDX_28 \
FLAG( 7, 0, EDX, 29, 1, ARCH_CAPABILITIES, ANY, 9, FALSE) \
CPUID_7_EDX_31
/* LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME, MON SUPP, HWV, CPL3 */
#define CPUID_FIELD_DATA_LEVEL_A \
@@ -958,7 +949,6 @@ FIELD( 88, 0, EAX, 16, 8, GUEST_PHYS_ADDR_SZ, YES, 8, FALSE) \
FLAG( 88, 0, EBX, 0, 1, CLZERO, YES, 14, TRUE) \
FLAG( 88, 0, EBX, 1, 1, IRPERF, NO, 0, FALSE) \
FLAG( 88, 0, EBX, 2, 1, XSAVE_ERR_PTR, NO, 0, FALSE) \
FLAG( 88, 0, EBX, 12, 1, IBPBONLY, ANY, 9, FALSE) \
FIELD( 88, 0, ECX, 0, 8, LEAF88_CORE_COUNT, YES, 4, FALSE) \
FIELD( 88, 0, ECX, 12, 4, APICID_COREID_SIZE, YES, 7, FALSE) \
FIELD( 88, 0, ECX, 16, 2, PERFTSC_SIZE, NO, 0, FALSE)
+1 -26
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2018 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
@@ -24,7 +24,6 @@
#ifndef _X86MSR_H_
#define _X86MSR_H_
#include <asm/msr-index.h>
#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_VMX
@@ -85,8 +84,6 @@ 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_PRED_CMD 0x00000049
#define MSR_BIOS_UPDT_TRIG 0x00000079
#define MSR_BIOS_SIGN_ID 0x0000008b
#define MSR_PERFCTR0 0x000000c1
@@ -115,21 +112,7 @@ MSRQuery;
#define MSR_TSC_AUX 0xc0000103
#define MSR_BD_TSC_RATIO 0xc0000104
#define IA32_MSR_ARCH_CAPABILITIES 0x10a
#define MSR_ARCH_CAPABILITIES_RDCL_NO (1ULL << 0)
#define MSR_ARCH_CAPABILITIES_IBRS_ALL (1ULL << 1)
#define MSR_ARCH_CAPABILITIES_RSBA (1ULL << 2)
#define MSR_FLUSH_CMD 0x10b
#define MSR_FLUSH_CMD_FLUSH_L1D 1
#define MSR_SPEC_CTRL_IBRS (1UL << 0)
#define MSR_SPEC_CTRL_STIBP (1UL << 1)
#define MSR_PRED_CMD_IBPB (1UL << 0)
#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
@@ -453,9 +436,7 @@ 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
@@ -497,8 +478,6 @@ 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.
@@ -633,11 +612,7 @@ 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
+1 -4
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2014,2016,2018 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2014,2016 VMware, Inc. All rights reserved.
*
* This program 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,7 +39,6 @@
#include "vm_basic_types.h"
#include "x86types.h"
#include "vm_pagetable.h"
#include "x86paging_common.h"
#define LM_PTE_PFN_MASK CONST64U(0xffffffffff000)
#define LM_PTE_2_PFN(_pte) (((_pte) & LM_PTE_PFN_MASK) >> PT_PTE_PFN_SHIFT)
@@ -71,8 +70,6 @@
#define LM_MAKE_L1E(_pfn, _avail, _flags) LM_MAKE_PTE(_pfn, _avail, _flags)
/*
* x86-64 architecture requires implementations supporting less than
* full 64-bit VAs to ensure that all virtual addresses are in canonical
+7 -14
View File
@@ -73,9 +73,6 @@ static Bool LinuxDriverCheckPadding(void);
struct VMXLinuxState linuxState;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
typedef int vm_fault_t;
#endif
/*
*----------------------------------------------------------------------
@@ -100,9 +97,9 @@ long LinuxDriver_Ioctl(struct file *filp, u_int iocmd,
static int LinuxDriver_Close(struct inode *inode, struct file *filp);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
static vm_fault_t LinuxDriverFault(struct vm_fault *fault);
static int LinuxDriverFault(struct vm_fault *fault);
#else
static vm_fault_t LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault);
static int LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault);
#endif
static int LinuxDriverMmap(struct file *filp, struct vm_area_struct *vma);
@@ -219,7 +216,7 @@ LinuxDriverEstimateTSCkHz(void)
*----------------------------------------------------------------------
*/
static void
LinuxDriverEstimateTSCkHzDeferred(struct timer_list *data)
LinuxDriverEstimateTSCkHzDeferred(unsigned long data)
{
LinuxDriverEstimateTSCkHz();
}
@@ -254,7 +251,9 @@ LinuxDriverInitTSCkHz(void)
}
LinuxDriverReadTSCAndUptime(&tsckHzStartTime);
tscTimer.function = LinuxDriverEstimateTSCkHzDeferred;
tscTimer.expires = jiffies + 4 * HZ;
tscTimer.data = 0;
add_timer(&tscTimer);
}
@@ -336,13 +335,7 @@ init_module(void)
linuxState.deviceName, linuxState.major, linuxState.minor);
HostIF_InitUptime();
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) && !defined(timer_setup)
init_timer(&tscTimer);
tscTimer.function = (void *)LinuxDriverEstimateTSCkHzDeferred;
tscTimer.data = (unsigned long)&tscTimer;
#else
timer_setup(&tscTimer, LinuxDriverEstimateTSCkHzDeferred, 0);
#endif
LinuxDriverInitTSCkHz();
Vmx86_InitIDList();
@@ -597,7 +590,7 @@ LinuxDriver_Close(struct inode *inode, // IN
*-----------------------------------------------------------------------------
*/
static vm_fault_t
static int
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
LinuxDriverFault(struct vm_fault *fault) //IN/OUT
#else
@@ -984,7 +977,7 @@ LinuxDriverReadTSC(void *data, // OUT: TSC values
*-----------------------------------------------------------------------------
*/
__always_inline static Bool
__attribute__((always_inline)) static Bool
LinuxDriverSyncReadTSCs(uint64 *delta) // OUT: TSC max - TSC min
{
TSCDelta tscDelta;
+225 -151
View File
@@ -47,16 +47,13 @@
#include <asm/asm.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
#include <asm/uaccess.h>
#include <asm/irq_vectors.h>
#include <linux/capability.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/hrtimer.h>
#include <linux/signal.h>
#include <linux/taskstats_kern.h> // For linux/sched/signal.h without version check
#include <linux/eventfd.h>
#include "vmware.h"
#include "x86apic.h"
@@ -77,7 +74,6 @@
#include "pgtbl.h"
#include "versioned_atomic.h"
#include "compat_poll.h"
#if !defined(CONFIG_HIGH_RES_TIMERS)
#error CONFIG_HIGH_RES_TIMERS required for acceptable performance
@@ -119,7 +115,13 @@
*/
#define LOCKED_PAGE_SLACK 10000
u64 uptime_base;
static struct {
Atomic_uint64 uptimeBase;
VersionedAtomic version;
uint64 monotimeBase;
unsigned long jiffiesBase;
struct timer_list timer;
} uptimeState;
/*
* First Page Locking strategy
@@ -178,21 +180,6 @@ u64 uptime_base;
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
/*
*-----------------------------------------------------------------------------
*
@@ -606,15 +593,6 @@ HostIF_FastClockUnlock(int callerID) // IN
MutexUnlock(&fastClockMutex, callerID);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
static int crosspage_set_exec(pte_t *pte, unsigned long addr, void *data)
{
struct page *p = data;
set_pte(pte, mk_pte(p, VM_PAGE_KERNEL_EXEC));
return 0;
}
#endif
/*
*----------------------------------------------------------------------
@@ -635,29 +613,7 @@ static int crosspage_set_exec(pte_t *pte, unsigned long addr, void *data)
static void *
MapCrossPage(struct page *p) // IN:
{
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 8, 0)
return vmap(&p, 1, VM_MAP, VM_PAGE_KERNEL_EXEC);
#else
void *addr;
addr = vmap(&p, 1, VM_MAP, VM_PAGE_KERNEL_EXEC);
if (!addr)
return NULL;
/* Starting with 5.8, vmap() always sets the NX bit, but the cross
* page needs to be executable. */
if (apply_to_page_range(current->mm, (unsigned long)addr, PAGE_SIZE,
crosspage_set_exec, p)) {
vunmap(addr);
return NULL;
}
preempt_disable();
__flush_tlb_all();
preempt_enable();
return addr;
#endif
}
@@ -1538,7 +1494,14 @@ unsigned int
HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN
unsigned int currentlyLockedPages) // IN
{
unsigned int totalPhysicalPages = compat_totalram_pages();
/*
* This variable is available and exported to modules,
* since at least 2.6.0.
*/
extern unsigned long totalram_pages;
unsigned int totalPhysicalPages = totalram_pages;
/*
* Use the memory information linux exports as of late for a more
@@ -1553,38 +1516,18 @@ 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 = hugePages + reservedPages;
unsigned int anonPages;
unsigned int lockedPages = global_page_state(NR_PAGETABLE) +
global_page_state(NR_SLAB_UNRECLAIMABLE) +
global_page_state(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 swapPages = BYTES_2_PAGES(linuxState.swapSize);
/* global_page_state is global_zone_page_state in 4.14. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
lockedPages += global_zone_page_state(NR_PAGETABLE);
#else
lockedPages += global_page_state(NR_PAGETABLE);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
/* NR_SLAB_* converted to byte counters in 5.9 */
lockedPages += global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
/* NR_SLAB_* moved from zone to node in 4.13. */
lockedPages += global_node_page_state(NR_SLAB_UNRECLAIMABLE);
#else
lockedPages += global_page_state(NR_SLAB_UNRECLAIMABLE);
#endif
/* NR_UNEVICTABLE moved from global to node in 4.8. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
lockedPages += global_node_page_state(NR_UNEVICTABLE);
#else
lockedPages += global_page_state(NR_UNEVICTABLE);
#endif
/* NR_ANON_MAPPED moved & changed name in 4.8. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
anonPages = global_node_page_state(NR_ANON_MAPPED);
#else
anonPages = global_page_state(NR_ANON_PAGES);
#endif
if (anonPages > swapPages) {
lockedPages += anonPages - swapPages;
}
@@ -1639,6 +1582,146 @@ 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);
}
/*
*----------------------------------------------------------------------
*
@@ -1650,7 +1733,8 @@ HostIF_WaitForFreePages(unsigned int timeoutMs) // IN:
* None
*
* Side effects:
* Sets the initial value for the uptime base.
* Sets the initial values for the uptime state, and schedules
* the uptime timer.
*
*----------------------------------------------------------------------
*/
@@ -1658,7 +1742,17 @@ HostIF_WaitForFreePages(unsigned int timeoutMs) // IN:
void
HostIF_InitUptime(void)
{
uptime_base = ktime_get_ns();
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);
}
@@ -1667,13 +1761,13 @@ HostIF_InitUptime(void)
*
* HostIF_CleanupUptime --
*
* No-op, left for backward compatibility.
* Cleanup uptime state, called at module unloading time.
*
* Results:
* None
*
* Side effects:
* None
* Deschedule the uptime timer.
*
*----------------------------------------------------------------------
*/
@@ -1681,6 +1775,7 @@ HostIF_InitUptime(void)
void
HostIF_CleanupUptime(void)
{
del_timer_sync(&uptimeState.timer);
}
@@ -1704,10 +1799,9 @@ HostIF_CleanupUptime(void)
uint64
HostIF_ReadUptime(void)
{
u64 tm;
unsigned long jifs;
tm = ktime_get_ns();
return (tm - uptime_base) / (NSEC_PER_SEC / UPTIME_FREQ);
return HostIFReadUptimeWork(&jifs);
}
@@ -2027,27 +2121,6 @@ HostIF_VMLockIsHeld(VMDriver *vm) // IN
#if defined(CONFIG_SMP) || defined(CONFIG_X86_UP_IOAPIC) || \
defined(CONFIG_X86_UP_APIC) || defined(CONFIG_X86_LOCAL_APIC)
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 8, 0)
static long compat_copy_from_kernel_nofault(void *dst, VA src, size_t size)
{
mm_segment_t old_fs;
long ret;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = HostIF_CopyFromUser(dst, src, size);
set_fs(old_fs);
return ret;
}
#else
static long compat_copy_from_kernel_nofault(void *dst, VA src, size_t size)
{
return copy_from_kernel_nofault(dst, (const void *)src, size);
}
#endif
/*
*----------------------------------------------------------------------
*
@@ -2067,11 +2140,15 @@ static long compat_copy_from_kernel_nofault(void *dst, VA src, size_t size)
static Bool
isVAReadable(VA r) // IN:
{
mm_segment_t old_fs;
uint32 dummy;
long ret;
int ret;
old_fs = get_fs();
set_fs(get_ds());
r = APICR_TO_ADDR(r, APICR_VERSION);
ret = compat_copy_from_kernel_nofault(&dummy, r, sizeof(dummy));
ret = HostIF_CopyFromUser(&dummy, r, sizeof dummy);
set_fs(old_fs);
return ret == 0;
}
@@ -2101,7 +2178,7 @@ SetVMAPICAddr(VMDriver *vm, // IN/OUT: driver state
volatile void *hostapic;
ASSERT_ON_COMPILE(APICR_SIZE <= PAGE_SIZE);
hostapic = (volatile void *) ioremap(ma, PAGE_SIZE);
hostapic = (volatile void *) ioremap_nocache(ma, PAGE_SIZE);
if (hostapic) {
if ((APIC_VERSIONREG(hostapic) & 0xF0) == 0x10) {
vm->hostAPIC.base = (volatile uint32 (*)[4]) hostapic;
@@ -2257,41 +2334,44 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
uint64 *args) // IN:
{
struct file *file;
mm_segment_t old_fs;
int res;
int waitFD = args[0];
int timeoutms = args[2];
uint64 value;
struct poll_wqueues table;
unsigned int mask;
file = vmware_fget(waitFD);
if (file == NULL) {
return MX_WAITERROR;
}
poll_initwait(&table);
current->state = TASK_INTERRUPTIBLE;
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
vm->vmhost->vcpuSemaTask[vcpuid] = NULL;
old_fs = get_fs();
set_fs(get_ds());
{
struct poll_wqueues table;
unsigned int mask;
poll_initwait(&table);
current->state = TASK_INTERRUPTIBLE;
mask = file->f_op->poll(file, &table.pt);
if (!(mask & (POLLIN | POLLERR | POLLHUP))) {
vm->vmhost->vcpuSemaTask[vcpuid] = current;
schedule_timeout(timeoutms * HZ / 1000); // convert to Hz
vm->vmhost->vcpuSemaTask[vcpuid] = NULL;
}
current->state = TASK_RUNNING;
poll_freewait(&table);
}
current->state = TASK_RUNNING;
poll_freewait(&table);
/*
* Userland only writes in multiples of sizeof(uint64). This will allow
* the code to happily deal with a pipe or an eventfd. We only care about
* reading no bytes (EAGAIN - non blocking fd) or sizeof(uint64).
*
* Upstream Linux changed the function parameter types/ordering in 4.14.0.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
res = kernel_read(file, file->f_pos, (char *)&value, sizeof value);
#else
res = kernel_read(file, &value, sizeof value, &file->f_pos);
#endif
res = file->f_op->read(file, (char *) &value, sizeof value, &file->f_pos);
if (res == sizeof value) {
res = MX_WAITNORMAL;
} else {
@@ -2300,6 +2380,7 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
}
}
set_fs(old_fs);
fput(file);
/*
@@ -2382,8 +2463,8 @@ HostIF_SemaphoreForceWakeup(VMDriver *vm, // IN:
int
HostIF_SemaphoreSignal(uint64 *args) // IN:
{
struct eventfd_ctx *eventfd;
struct file *file;
mm_segment_t old_fs;
int res;
int signalFD = args[1];
uint64 value = 1; // make an eventfd happy should it be there
@@ -2393,34 +2474,22 @@ HostIF_SemaphoreSignal(uint64 *args) // IN:
return MX_WAITERROR;
}
/*
* If it's eventfd, use specific eventfd interface as kernel writes
* to eventfd may not be allowed in kernel 5.10 and later.
*/
eventfd = eventfd_ctx_fileget(file);
if (!IS_ERR(eventfd)) {
eventfd_signal(eventfd, 1);
fput(file);
return MX_WAITNORMAL;
}
old_fs = get_fs();
set_fs(get_ds());
/*
* Always write sizeof(uint64) bytes. This works fine for eventfd and
* pipes. The data written is formatted to make an eventfd happy should
* it be present.
*
* Upstream Linux changed the function parameter types/ordering in 4.14.0.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
res = kernel_write(file, (char *)&value, sizeof value, file->f_pos);
#else
res = kernel_write(file, &value, sizeof value, &file->f_pos);
#endif
res = file->f_op->write(file, (char *) &value, sizeof value, &file->f_pos);
if (res == sizeof value) {
res = MX_WAITNORMAL;
}
set_fs(old_fs);
fput(file);
/*
@@ -2939,9 +3008,12 @@ static int
HostIFFastClockThread(void *unused) // IN:
{
int res;
mm_segment_t oldFS;
unsigned int rate = 0;
unsigned int prevRate = 0;
oldFS = get_fs();
set_fs(KERNEL_DS);
allow_signal(SIGKILL);
while ((rate = linuxState.fastClockRate) > MIN_RATE) {
@@ -2964,6 +3036,8 @@ HostIFFastClockThread(void *unused) // IN:
}
out:
set_fs(oldFS);
/*
* Do not exit thread until we are told to do so.
*/
@@ -3061,7 +3135,7 @@ HostIF_SetFastClockRate(unsigned int rate) // IN: Frequency in Hz.
}
} else {
if (linuxState.fastClockThread) {
send_sig(SIGKILL, linuxState.fastClockThread, 1);
force_sig(SIGKILL, linuxState.fastClockThread);
kthread_stop(linuxState.fastClockThread);
linuxState.fastClockThread = NULL;
@@ -3107,7 +3181,7 @@ HostIF_MapUserMem(VA addr, // IN: User memory virtual address
ASSERT(handle);
if (!write_access_ok(p, size)) {
if (!access_ok(VERIFY_WRITE, p, size)) {
printk(KERN_ERR "%s: Couldn't verify write to uva 0x%p with size %"
FMTSZ"u\n", __func__, p, size);
+1 -1
View File
@@ -107,7 +107,7 @@ prebuild:: ;
postbuild:: ;
$(DRIVER_KO): prebuild
$(MAKE) -C $(BUILD_DIR) M=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
$(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) modules
$(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \
MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild
+1 -2
View File
@@ -20,7 +20,6 @@
INCLUDE := -I$(SRCROOT)
EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/netif_trans_update.c,-DVMW_NETIF_TRANS_UPDATE, )
obj-m += $(DRIVER).o
@@ -32,6 +31,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 .cache.mk \
rm -rf $(DRIVER).o $(DRIVER).mod.o $(DRIVER).mod.c $(DRIVER).ko \
.tmp_versions Module.symvers Modules.symvers Module.markers \
modules.order $($(DRIVER)-y) .*.cmd .*.o.flags
+7 -6
View File
@@ -66,7 +66,7 @@
#endif
#if LOGLEVEL >= 4
static u64 vnetTime;
static struct timeval vnetTime;
#endif
typedef struct VNetBridge VNetBridge;
@@ -693,7 +693,7 @@ VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack
netif_rx_ni(clone);
# if LOGLEVEL >= 4
vnetTime = ktime_get_ns();
do_gettimeofday(&vnetTime);
# endif
}
}
@@ -1490,11 +1490,12 @@ VNetBridgeReceiveFromDev(struct sk_buff *skb, // IN: packet to receive
# if LOGLEVEL >= 4
{
u64 now;
now = ktime_get_ns();
struct timeval now;
do_gettimeofday(&now);
LOG(3, (KERN_DEBUG "bridge-%s: time %d\n",
bridge->name, (int)((now - vnetTime) / NSEC_PER_USEC)));
bridge->name,
(int)((now.tv_sec * 1000000 + now.tv_usec)
- (vnetTime.tv_sec * 1000000 + vnetTime.tv_usec))));
}
# endif
+3 -1
View File
@@ -337,7 +337,9 @@ typedef netdev_features_t compat_netdev_features_t;
typedef u32 compat_netdev_features_t;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) || defined(VMW_NETIF_TRANS_UPDATE)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) || \
(defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= 0x0704) || \
(defined(CONFIG_SUSE_KERNEL) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 73))
#define compat_netif_trans_update(d) netif_trans_update(d)
#else
#define compat_netif_trans_update(d) do { (d)->trans_start = jiffies; } while (0)
-39
View File
@@ -1,39 +0,0 @@
/*********************************************************
* Copyright (C) 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
* Free Software Foundation version 2 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public 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 there is netif_trans_update, which got introduced from 4.7.0
* Older kernels may have this function backported by vendors.
*/
#include "compat_version.h"
#include "compat_autoconf.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
# error This compile test intentionally fails.
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)
#include <linux/netdevice.h>
void test_netif_trans_update(struct net_device *dev)
{
netif_trans_update(dev);
}
#endif
-9
View File
@@ -161,14 +161,6 @@ 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,
@@ -176,7 +168,6 @@ static struct file_operations fops = {
.release = single_release,
};
#endif
#endif
/*
+19 -60
View File
@@ -78,55 +78,11 @@ 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_frag(frag) kmap((frag)->page)
# define compat_kunmap_frag(page) kunmap((frag)->page)
# define compat_kmap(page) kmap(page)
# define compat_kunmap(page) kunmap(page)
#else
# 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
#if COMPAT_LINUX_VERSION_CHECK_LT(5, 10, 0)
static inline
__wsum compat_csum_and_copy_to_user(const void *src, void __user *dst, int len)
{
int err;
__wsum ret;
ret = csum_and_copy_to_user(src, dst, len, 0, &err);
return err ? 0 : ret;
}
#else
static inline
__wsum compat_csum_and_copy_to_user(const void *src, void __user *dst, int len)
{
return csum_and_copy_to_user(src, dst, len);
}
# define compat_kmap(page) kmap((page).p)
# define compat_kunmap(page) kunmap((page).p)
#endif
/*
@@ -186,7 +142,7 @@ VNetUserIfMapPtr(VA uAddr, // IN: pointer to user memory
struct page **p, // OUT: locked page
void **ptr) // OUT: kernel mapped pointer
{
if (!write_access_ok((void *)uAddr, size) ||
if (!access_ok(VERIFY_WRITE, (void *)uAddr, size) ||
(((uAddr + size - 1) & ~(PAGE_SIZE - 1)) !=
(uAddr & ~(PAGE_SIZE - 1)))) {
return -EINVAL;
@@ -581,6 +537,7 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy
char *buf) // OUT: where to copy data
{
unsigned int csum;
int err = 0;
int len = skb_headlen(skb) - offset;
char *curr = buf;
const skb_frag_t *frag;
@@ -593,27 +550,29 @@ VNetCsumCopyDatagram(const struct sk_buff *skb, // IN: skb to copy
return -EINVAL;
}
csum = compat_csum_and_copy_to_user(skb->data + offset, curr, len);
if (!csum)
return -EFAULT;
csum = csum_and_copy_to_user(skb->data + offset, curr, len, 0, &err);
if (err) {
return err;
}
curr += len;
for (frag = skb_shinfo(skb)->frags;
frag != skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags;
frag++) {
if (compat_skb_frag_size(frag) > 0) {
if (frag->size > 0) {
unsigned int tmpCsum;
const void *vaddr;
vaddr = compat_kmap_frag(frag);
tmpCsum = compat_csum_and_copy_to_user(vaddr + compat_skb_frag_off(frag),
curr, compat_skb_frag_size(frag));
compat_kunmap_frag(frag);
vaddr = compat_kmap(frag->page);
tmpCsum = csum_and_copy_to_user(vaddr + frag->page_offset,
curr, frag->size, 0, &err);
compat_kunmap(frag->page);
if (!tmpCsum)
return -EFAULT;
if (err) {
return err;
}
csum = csum_block_add(csum, tmpCsum, curr - buf);
curr += compat_skb_frag_size(frag);
curr += frag->size;
}
}
-9
View File
@@ -35,8 +35,6 @@
#endif
#endif
#include <linux/pci_ids.h>
/* LSILogic 53C1030 Parallel SCSI controller
* LSILogic SAS1068 SAS controller
*/
@@ -55,10 +53,7 @@
* 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
@@ -75,11 +70,7 @@
#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