Compare commits

..
10 Commits
Author SHA1 Message Date
Michal Kubecek 0dee99d40a Merge branch 'master' into player-12.5.2 2018-04-02 15:37:19 +02:00
Michal Kubecek 343e2bbbc9 mark branch player-12.5.2 as retired 2018-04-02 15:33:39 +02:00
Michal Kubecek 77a6966b97 misc: warn if branch is marked as retired
When "make" or "make install is issued on branch marked as retired, warn
user about the fact.
2018-04-02 15:31:34 +02:00
Michal Kubecek 625084e96a misc: add INSTALL document
Add file INSTALL explaining how to use the repository (get patched sources,
build the modules and install them).
2018-02-04 21:48:58 +01:00
Michal Kubecek 1d91cc5b6a misc: add top level makefile
Add a top level makefile to make common tasks easier. Supported targets:

  make           - build modules
  make install   - install modules (honors DESTDIR)
  make clean     - clean up
  make tarballs  - create source tarballs from current HEAD

Note: "make tarballs" uses "git archive" so that it only works in a local
copy of the git repository, not in a directory created by unpacking
a tarball.

Add *.tar to .gitignore to hide tarballs created by "make tarballs".
2018-02-04 21:48:58 +01:00
Michal Kubecek 6fd497d954 misc: update README
Fix a type and clarify the part about building against older kernels.
2018-02-02 18:09:09 +01:00
Michal Kubecek 3fc524fd27 misc: ignore .cache.mk
Add .cache.mk files to .gitignore.
2018-02-02 18:08:41 +01:00
Michal Kubecek 50b2ddbda3 vmnet: use standard definition of PCI_VENDOR_ID_VMWARE if available
The PCI_DEVICE_ID_VMWARE_VMXNET3 macro is defined in mainline pci_ids.h
since commit b1226c7db1d9 ("vmxnet3: Move PCI Id to pci_ids.h") in
v4.10-rc1.
2017-05-31 09:21:31 +02:00
Michal Kubecek bab1fc0501 all: replace get_user_pages() write/force parameters with flags
Since commit 3b913179c3fa ("mm: replace get_user_pages_locked()
write/force parameters with gup_flags") in v4.9-rc2, get_user_pages()
has one flags argument rather than separate write and force flags.
2017-05-31 09:21:31 +02:00
Michal Kubecek 04b5b8ff63 vmnet: use standard definition of PCI_VENDOR_ID_VMWARE if available
The PCI_VENDOR_ID_VMWARE macro is defined in mainline pci_ids.h since
commit 94e57fea6202 ("PCI: Move PCI_VENDOR_ID_VMWARE to pci_ids.h")
in v3.18-rc1.
2017-05-31 09:21:31 +02:00
22 changed files with 714 additions and 330 deletions

No files matched your search

+2
View File
@@ -3,6 +3,8 @@
*.ko
*.ko.cmd
*.mod.c
*.tar
.tmp_versions
.cache.mk
Module.symvers
modules.order
+197
View File
@@ -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 vmmon-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.
+48
View File
@@ -0,0 +1,48 @@
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)
tarballs: $(TARBALLS)
+8 -3
View File
@@ -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.
+7
View File
@@ -0,0 +1,7 @@
*-----------------------------------------------------------------------------
* Branch player-12.5.2 has been retired on 2017-05-31 and has not been
* receiving any updates since. Please switch to latest 12.5.x version
* available.
*
* Latest kernel version this branch is intended to work with is 4.10.
*-----------------------------------------------------------------------------
+8 -8
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -122,10 +122,14 @@ EXTERN MPN HostIF_GetNextAnonPage(VMDriver *vm, MPN mpn);
EXTERN int HostIF_GetLockedPageList(VMDriver *vm, VA64 uAddr,
unsigned int numPages);
EXTERN int HostIF_ReadPage(VMDriver *vm, MPN mpn, VA64 addr, Bool kernelBuffer);
EXTERN int HostIF_WritePage(VMDriver *vm, MPN mpn, VA64 addr,
Bool kernelBuffer);
EXTERN int HostIF_ReadPage(MPN mpn, VA64 addr, Bool kernelBuffer);
EXTERN int HostIF_WritePage(MPN mpn, VA64 addr, Bool kernelBuffer);
#ifdef _WIN32
/* Add a HostIF_ReadMachinePage() if/when needed */
EXTERN int HostIF_WriteMachinePage(MPN mpn, VA64 addr);
#else
#define HostIF_WriteMachinePage(_a, _b) HostIF_WritePage((_a), (_b), TRUE)
#endif
#if defined __APPLE__
// There is no need for a fast clock lock on Mac OS.
#define HostIF_FastClockLock(_callerID) do {} while (0)
@@ -141,8 +145,4 @@ EXTERN void HostIF_FreeMachinePage(MPN mpn);
EXTERN int HostIF_SafeRDMSR(uint32 msr, uint64 *val);
#if defined __APPLE__
EXTERN void HostIF_PageUnitTest(void);
#endif
#endif // ifdef _HOSTIF_H_
+13 -11
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -88,7 +88,6 @@
#include "vmware.h"
#include "hostif.h"
#include "vmx86.h"
#include "memtrack.h"
@@ -147,11 +146,12 @@ typedef struct MemTrackHT {
typedef uint64 MemTrackHTKey;
typedef struct MemTrack {
VMDriver *vm; /* The VM instance. */
unsigned numPages; /* Number of pages tracked. */
MemTrackDir1 dir1; /* First level directory. */
MemTrackHT vpnHashTable; /* VPN to entry hashtable. */
#if defined(MEMTRACK_MPN_LOOKUP)
MemTrackHT mpnHashTable; /* MPN to entry hashtable. */
#endif
} MemTrack;
/*
@@ -304,9 +304,11 @@ MemTrackCleanup(MemTrack *mt) // IN
if (mt->vpnHashTable.pages[idx] != NULL) {
HostIF_FreePage(mt->vpnHashTable.pages[idx]);
}
#if defined(MEMTRACK_MPN_LOOKUP)
if (mt->mpnHashTable.pages[idx] != NULL) {
HostIF_FreePage(mt->mpnHashTable.pages[idx]);
}
#endif
}
HostIF_FreeKernelMem(mt);
@@ -330,7 +332,7 @@ MemTrackCleanup(MemTrack *mt) // IN
*/
MemTrack *
MemTrack_Init(VMDriver *vm) // IN:
MemTrack_Init(void)
{
MemTrack *mt;
unsigned idx;
@@ -347,7 +349,6 @@ MemTrack_Init(VMDriver *vm) // IN:
goto error;
}
memset(mt, 0, sizeof *mt);
mt->vm = vm;
for (idx = 0; idx < MEMTRACK_HT_PAGES; idx++) {
MemTrackHTPage *htPage = MemTrackAllocPage();
@@ -359,6 +360,7 @@ MemTrack_Init(VMDriver *vm) // IN:
mt->vpnHashTable.pages[idx] = htPage;
}
#if defined(MEMTRACK_MPN_LOOKUP)
for (idx = 0; idx < MEMTRACK_HT_PAGES; idx++) {
MemTrackHTPage *htPage = MemTrackAllocPage();
@@ -368,6 +370,7 @@ MemTrack_Init(VMDriver *vm) // IN:
}
mt->mpnHashTable.pages[idx] = htPage;
}
#endif
return mt;
@@ -406,8 +409,6 @@ MemTrack_Add(MemTrack *mt, // IN
MemTrackDir3 *dir3;
MEMTRACK_IDX2DIR(idx, p1, p2, p3);
ASSERT(HostIF_VMLockIsHeld(mt->vm));
if (p1 >= MEMTRACK_DIR1_ENTRIES ||
p2 >= MEMTRACK_DIR2_ENTRIES ||
p3 >= MEMTRACK_DIR3_ENTRIES) {
@@ -429,7 +430,9 @@ MemTrack_Add(MemTrack *mt, // IN
ent->mpn = mpn;
MemTrackHTInsert(&mt->vpnHashTable, ent, &ent->vpnChain, ent->vpn);
#if defined(MEMTRACK_MPN_LOOKUP)
MemTrackHTInsert(&mt->mpnHashTable, ent, &ent->mpnChain, ent->mpn);
#endif
mt->numPages++;
@@ -458,7 +461,6 @@ MemTrack_LookupVPN(MemTrack *mt, // IN
VPN64 vpn) // IN
{
MemTrackEntry *next = *MemTrackHTLookup(&mt->vpnHashTable, vpn);
ASSERT(HostIF_VMLockIsHeld(mt->vm));
while (next != NULL) {
if (next->vpn == vpn) {
@@ -471,6 +473,7 @@ MemTrack_LookupVPN(MemTrack *mt, // IN
}
#if defined(MEMTRACK_MPN_LOOKUP)
/*
*----------------------------------------------------------------------
*
@@ -490,9 +493,7 @@ MemTrackEntry *
MemTrack_LookupMPN(MemTrack *mt, // IN
MPN mpn) // IN
{
MemTrackEntry *next;
ASSERT(HostIF_VMLockIsHeld(mt->vm));
next = *MemTrackHTLookup(&mt->mpnHashTable, mpn);
MemTrackEntry *next = *MemTrackHTLookup(&mt->mpnHashTable, mpn);
while (next != NULL) {
if (next->mpn == mpn) {
@@ -503,6 +504,7 @@ MemTrack_LookupMPN(MemTrack *mt, // IN
return NULL;
}
#endif
/*
+10 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -31,22 +31,30 @@
#define INCLUDE_ALLOW_VMCORE
#include "includeCheck.h"
#if defined(VMX86_DEBUG)
#define MEMTRACK_MPN_LOOKUP
#endif
struct MemTrack;
typedef struct MemTrackEntry {
VPN64 vpn;
MPN mpn;
struct MemTrackEntry *vpnChain;
#if defined(MEMTRACK_MPN_LOOKUP)
struct MemTrackEntry *mpnChain;
#endif
} MemTrackEntry;
typedef void (MemTrackCleanupCb)(void *cData, MemTrackEntry *entry);
extern struct MemTrack *MemTrack_Init(VMDriver *vm);
extern struct MemTrack *MemTrack_Init(void);
extern unsigned MemTrack_Cleanup(struct MemTrack *mt, MemTrackCleanupCb *cb,
void *cbData);
extern MemTrackEntry *MemTrack_Add(struct MemTrack *mt, VPN64 vpn, MPN mpn);
extern MemTrackEntry *MemTrack_LookupVPN(struct MemTrack *mt, VPN64 vpn);
#if defined(MEMTRACK_MPN_LOOKUP)
extern MemTrackEntry *MemTrack_LookupMPN(struct MemTrack *mt, MPN mpn);
#endif
#endif // _MEMTRACK_H_
+2 -30
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-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,9 +39,6 @@
# include <linux/string.h> /* memset() in the kernel */
# define EXPORT_SYMTAB
# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
# define LINUX_GDT_IS_RO
# endif
#else
# include <string.h>
#endif
@@ -63,13 +60,6 @@
#include "apic.h"
#include "x86perfctr.h"
#ifdef LINUX_GDT_IS_RO
# include <asm/desc.h>
# define default_rw_gdt get_current_gdt_rw()
#else
# define default_rw_gdt NULL
#endif
#if defined(_WIN64)
# include "x86.h"
# include "vmmon-asm-x86-64.h"
@@ -701,28 +691,11 @@ TaskRestoreHostGDTTRLDT(Descriptor *tempGDTBase,
*/
desc = (Descriptor *)((VA)HOST_KERNEL_LA_2_VA(hostGDT64.offset + tr));
#ifdef LINUX_GDT_IS_RO
/*
* If GDT is read-only, we must always load TR from alternative gdt,
* otherwise CPU gets page fault when marking TR busy.
*/
{
DTR64 rwGDT64;
rwGDT64.offset = (unsigned long)tempGDTBase;
rwGDT64.limit = hostGDT64.limit;
Desc_SetType((Descriptor *)((unsigned long)tempGDTBase + tr), TASK_DESC);
_Set_GDT((DTR *)&rwGDT64);
SET_TR(tr);
_Set_GDT((DTR *)&hostGDT64);
}
#else
if (Desc_Type(desc) == TASK_DESC_BUSY) {
Desc_SetType(desc, TASK_DESC);
}
_Set_GDT((DTR *)&hostGDT64);
SET_TR(tr);
#endif
SET_LDT(ldt);
}
}
@@ -1774,8 +1747,7 @@ Task_Switch(VMDriver *vm, // IN
ASSERT(pCPU < ARRAYSIZE(hvRootPage) && pCPU < ARRAYSIZE(tmpGDT));
hvRootMPN = Atomic_Read64(&hvRootPage[pCPU]);
tempGDTBase = USE_TEMPORARY_GDT ? Atomic_ReadPtr(&tmpGDT[pCPU])
: default_rw_gdt;
tempGDTBase = USE_TEMPORARY_GDT ? Atomic_ReadPtr(&tmpGDT[pCPU]) : NULL;
/*
* We can't allocate memory with interrupts disabled on all hosts
+1 -30
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-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
@@ -720,35 +720,6 @@ cleanup:
}
/*
*----------------------------------------------------------------------
*
* Vmx86_LookupUserMPN --
*
* Look up the MPN of a locked user page by user VA under the VM lock.
*
* Results:
* A status code and the MPN on success.
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
int
Vmx86_LookupUserMPN(VMDriver *vm, // IN: VMDriver
VA64 uAddr, // IN: user VA of the page
MPN *mpn) // OUT
{
int ret;
HostIF_VMLock(vm, 38);
ret = HostIF_LookupUserMPN(vm, uAddr, mpn);
HostIF_VMUnlock(vm, 38);
return ret;
}
/*
*----------------------------------------------------------------------
*
+1 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2013,2015-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
@@ -106,7 +106,6 @@ extern PseudoTSC pseudoTSC;
#define MAX_LOCKED_PAGES (-1)
extern VMDriver *Vmx86_CreateVM(void);
extern int Vmx86_LookupUserMPN(VMDriver *vm, VA64 uAddr, MPN *mpn);
extern int Vmx86_ReleaseVM(VMDriver *vm);
extern int Vmx86_InitVM(VMDriver *vm, InitBlock *initParams);
extern int Vmx86_LateInitVM(VMDriver *vm);
-4
View File
@@ -24,11 +24,7 @@
* Include linux/cred.h via linux/sched.h - it is not nice, but
* as cpp does not have #ifexist...
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
#include <linux/sched.h>
#else
#include <linux/cred.h>
#endif
#if !defined(current_fsuid) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
#define current_uid() (current->uid)
+76 -24
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 2002-2017 VMware, Inc. All rights reserved.
* Copyright (C) 2002 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -30,32 +30,80 @@
#include <asm/pgtable.h>
/*
* p4d level appeared in 4.12.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
# define compat_p4d_offset(pgd, address) p4d_offset(pgd, address)
# define compat_p4d_present(p4d) p4d_present(p4d)
# define compat_p4d_large(p4d) p4d_large(p4d)
# define compat_p4d_pfn(p4d) p4d_pfn(p4d)
# define COMPAT_P4D_MASK P4D_MASK
typedef p4d_t compat_p4d_t;
/* pte_page() API modified in 2.3.23 to return a struct page * --hpreg */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
# define compat_pte_page pte_page
#else
# define compat_p4d_offset(pgd, address) (pgd)
# define compat_p4d_present(p4d) (1)
# define compat_p4d_large(p4d) (0)
# define compat_p4d_pfn(p4d) INVALID_MPN /* Not used */
# define COMPAT_P4D_MASK 0 /* Not used */
typedef pgd_t compat_p4d_t;
# include "compat_page.h"
# define compat_pte_page(_pte) virt_to_page(pte_page(_pte))
#endif
/* p[gu]d_large did not exist before 2.6.25 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
# define pud_large(pud) 0
# define pgd_large(pgd) 0
/* Appeared in 2.5.5 --hpreg */
#ifndef pte_offset_map
/* Appeared in SuSE 8.0's 2.4.18 --hpreg */
# ifdef pte_offset_atomic
# define pte_offset_map pte_offset_atomic
# define pte_unmap pte_kunmap
# else
# define pte_offset_map pte_offset
# define pte_unmap(_pte)
# endif
#endif
/* pud_pfn did not exist before 3.8. */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
# define pud_pfn(pud) INVALID_MPN
/* Appeared in 2.5.74-mmX --petr */
#ifndef pmd_offset_map
# define pmd_offset_map(pgd, address) pmd_offset(pgd, address)
# define pmd_unmap(pmd)
#endif
/*
* Appeared in 2.6.10-rc2-mm1. Older kernels did L4 page tables as
* part of pgd_offset, or they did not have L4 page tables at all.
* In 2.6.11 pml4 -> pgd -> pmd -> pte hierarchy was replaced by
* pgd -> pud -> pmd -> pte hierarchy.
*/
#ifdef PUD_MASK
# define compat_pgd_offset(mm, address) pgd_offset(mm, address)
# define compat_pgd_present(pgd) pgd_present(pgd)
# define compat_pud_offset(pgd, address) pud_offset(pgd, address)
# define compat_pud_present(pud) pud_present(pud)
typedef pgd_t compat_pgd_t;
typedef pud_t compat_pud_t;
#elif defined(pml4_offset)
# define compat_pgd_offset(mm, address) pml4_offset(mm, address)
# define compat_pgd_present(pml4) pml4_present(pml4)
# define compat_pud_offset(pml4, address) pml4_pgd_offset(pml4, address)
# define compat_pud_present(pgd) pgd_present(pgd)
typedef pml4_t compat_pgd_t;
typedef pgd_t compat_pud_t;
#else
# define compat_pgd_offset(mm, address) pgd_offset(mm, address)
# define compat_pgd_present(pgd) pgd_present(pgd)
# define compat_pud_offset(pgd, address) (pgd)
# define compat_pud_present(pud) (1)
typedef pgd_t compat_pgd_t;
typedef pgd_t compat_pud_t;
#endif
#define compat_pgd_offset_k(mm, address) pgd_offset_k(address)
/* Introduced somewhere in 2.6.0, + backported to some 2.4 RedHat kernels */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(pte_pfn)
# define pte_pfn(pte) page_to_pfn(compat_pte_page(pte))
#endif
/* A page_table_lock field is added to struct mm_struct in 2.3.10 --hpreg */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 10)
# define compat_get_page_table_lock(_mm) (&(_mm)->page_table_lock)
#else
# define compat_get_page_table_lock(_mm) NULL
#endif
@@ -80,8 +128,12 @@ typedef pgd_t compat_p4d_t;
#define VM_PAGE_KERNEL_EXEC PAGE_KERNEL
#endif
#else
#ifdef PAGE_KERNEL_EXECUTABLE
#define VM_PAGE_KERNEL_EXEC PAGE_KERNEL_EXECUTABLE
#else
#define VM_PAGE_KERNEL_EXEC PAGE_KERNEL_EXEC
#endif
#endif
#endif /* __COMPAT_PGTABLE_H__ */
+299 -59
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 2002,2014-2017 VMware, Inc. All rights reserved.
* Copyright (C) 2002,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -26,14 +26,154 @@
#include "compat_spinlock.h"
#include "compat_page.h"
/*
*-----------------------------------------------------------------------------
*
* PgtblPte2MPN --
*
* Returns the page structure associated to a Page Table Entry.
*
* This function is not allowed to schedule() because it can be called while
* holding a spinlock --hpreg
*
* Results:
* INVALID_MPN on failure
* mpn on success
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE MPN
PgtblPte2MPN(pte_t *pte) // IN
{
MPN mpn;
if (pte_present(*pte) == 0) {
return INVALID_MPN;
}
mpn = pte_pfn(*pte);
if (mpn >= INVALID_MPN) {
return INVALID_MPN;
}
return mpn;
}
/*
*-----------------------------------------------------------------------------
*
* PgtblPte2Page --
*
* Returns the page structure associated to a Page Table Entry.
*
* This function is not allowed to schedule() because it can be called while
* holding a spinlock --hpreg
*
* Results:
* The page structure if the page table entry points to a physical page
* NULL if the page table entry does not point to a physical page
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE struct page *
PgtblPte2Page(pte_t *pte) // IN
{
if (pte_present(*pte) == 0) {
return NULL;
}
return compat_pte_page(*pte);
}
/*
*-----------------------------------------------------------------------------
*
* PgtblPGD2PTELocked --
*
* Walks through the hardware page tables to try to find the pte
* associated to a virtual address.
*
* Results:
* pte. Caller must call pte_unmap if valid pte returned.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE pte_t *
PgtblPGD2PTELocked(compat_pgd_t *pgd, // IN: PGD to start with
VA addr) // IN: Address in the virtual address
// space of that process
{
compat_pud_t *pud;
pmd_t *pmd;
pte_t *pte;
if (compat_pgd_present(*pgd) == 0) {
return NULL;
}
pud = compat_pud_offset(pgd, addr);
if (compat_pud_present(*pud) == 0) {
return NULL;
}
pmd = pmd_offset_map(pud, addr);
if (pmd_present(*pmd) == 0) {
pmd_unmap(pmd);
return NULL;
}
pte = pte_offset_map(pmd, addr);
pmd_unmap(pmd);
return pte;
}
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2PTELocked --
*
* Walks through the hardware page tables to try to find the pte
* associated to a virtual address.
*
* Results:
* pte. Caller must call pte_unmap if valid pte returned.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE pte_t *
PgtblVa2PTELocked(struct mm_struct *mm, // IN: Mm structure of a process
VA addr) // IN: Address in the virtual address
// space of that process
{
return PgtblPGD2PTELocked(compat_pgd_offset(mm, addr), addr);
}
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2MPNLocked --
*
* Walks through the hardware page tables to try to find the pte
* associated to a virtual address. Then maps PTE to MPN.
* Retrieve MPN for a given va.
*
* Caller must call pte_unmap if valid pte returned. The mm->page_table_lock
* must be held, so this function is not allowed to schedule() --hpreg
*
* Results:
* INVALID_MPN on failure
@@ -48,66 +188,91 @@
static INLINE MPN
PgtblVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a process
VA addr) // IN: Address in the virtual address
// space of that process
{
pgd_t *pgd;
compat_p4d_t *p4d;
MPN mpn;
pte_t *pte;
pgd = pgd_offset(mm, addr);
if (pgd_present(*pgd) == 0) {
return INVALID_MPN;
pte = PgtblVa2PTELocked(mm, addr);
if (pte != NULL) {
MPN mpn = PgtblPte2MPN(pte);
pte_unmap(pte);
return mpn;
}
if (pgd_large(*pgd)) {
/* Linux kernel does not support PGD huge pages. */
/* return pgd_pfn(*pgd) + ((addr & PGD_MASK) >> PAGE_SHIFT); */
return INVALID_MPN;
}
p4d = compat_p4d_offset(pgd, addr);
if (compat_p4d_present(*p4d) == 0) {
return INVALID_MPN;
}
if (compat_p4d_large(*p4d)) {
mpn = compat_p4d_pfn(*p4d) + ((addr & ~COMPAT_P4D_MASK) >> PAGE_SHIFT);
} else {
pud_t *pud;
pud = pud_offset(p4d, addr);
if (pud_present(*pud) == 0) {
return INVALID_MPN;
}
if (pud_large(*pud)) {
mpn = pud_pfn(*pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
} else {
pmd_t *pmd;
pmd = pmd_offset(pud, addr);
if (pmd_present(*pmd) == 0) {
return INVALID_MPN;
}
if (pmd_large(*pmd)) {
mpn = pmd_pfn(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
} else {
pte_t *pte;
pte = pte_offset_map(pmd, addr);
if (pte_present(*pte) == 0) {
pte_unmap(pte);
return INVALID_MPN;
}
mpn = pte_pfn(*pte);
pte_unmap(pte);
}
}
}
if (mpn >= INVALID_MPN) {
mpn = INVALID_MPN;
}
return mpn;
return INVALID_MPN;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
/*
*-----------------------------------------------------------------------------
*
* PgtblKVa2MPNLocked --
*
* Retrieve MPN for a given kernel va.
*
* Caller must call pte_unmap if valid pte returned. The mm->page_table_lock
* must be held, so this function is not allowed to schedule() --hpreg
*
* Results:
* INVALID_MPN on failure
* mpn on success
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE MPN
PgtblKVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a caller
VA addr) // IN: Address in the virtual address
{
pte_t *pte;
pte = PgtblPGD2PTELocked(compat_pgd_offset_k(mm, addr), addr);
if (pte != NULL) {
MPN mpn = PgtblPte2MPN(pte);
pte_unmap(pte);
return mpn;
}
return INVALID_MPN;
}
#endif
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2PageLocked --
*
* Return the "page" struct for a given va.
*
* Results:
* struct page or NULL. The mm->page_table_lock must be held, so this
* function is not allowed to schedule() --hpreg
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE struct page *
PgtblVa2PageLocked(struct mm_struct *mm, // IN: Mm structure of a process
VA addr) // IN: Address in the virtual address
{
pte_t *pte;
pte = PgtblVa2PTELocked(mm, addr);
if (pte != NULL) {
struct page *page = PgtblPte2Page(pte);
pte_unmap(pte);
return page;
} else {
return NULL;
}
}
/*
*-----------------------------------------------------------------------------
*
@@ -133,10 +298,85 @@ PgtblVa2MPN(VA addr) // IN
/* current->mm is NULL for kernel threads, so use active_mm. */
mm = current->active_mm;
spin_lock(&mm->page_table_lock);
if (compat_get_page_table_lock(mm)) {
spin_lock(compat_get_page_table_lock(mm));
}
mpn = PgtblVa2MPNLocked(mm, addr);
spin_unlock(&mm->page_table_lock);
if (compat_get_page_table_lock(mm)) {
spin_unlock(compat_get_page_table_lock(mm));
}
return mpn;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
/*
*-----------------------------------------------------------------------------
*
* PgtblKVa2MPN --
*
* Walks through the hardware page tables of the current process to try to
* find the page structure associated to a virtual address.
*
* Results:
* Same as PgtblVa2MPNLocked()
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE MPN
PgtblKVa2MPN(VA addr) // IN
{
struct mm_struct *mm = current->active_mm;
MPN mpn;
if (compat_get_page_table_lock(mm)) {
spin_lock(compat_get_page_table_lock(mm));
}
mpn = PgtblKVa2MPNLocked(mm, addr);
if (compat_get_page_table_lock(mm)) {
spin_unlock(compat_get_page_table_lock(mm));
}
return mpn;
}
#endif
/*
*-----------------------------------------------------------------------------
*
* PgtblVa2Page --
*
* Walks through the hardware page tables of the current process to try to
* find the page structure associated to a virtual address.
*
* Results:
* Same as PgtblVa2PageLocked()
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static INLINE struct page *
PgtblVa2Page(VA addr) // IN
{
struct mm_struct *mm = current->active_mm;
struct page *page;
if (compat_get_page_table_lock(mm)) {
spin_lock(compat_get_page_table_lock(mm));
}
page = PgtblVa2PageLocked(mm, addr);
if (compat_get_page_table_lock(mm)) {
spin_unlock(compat_get_page_table_lock(mm));
}
return page;
}
#endif /* __PGTBL_H__ */
+9 -14
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-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
@@ -104,9 +104,7 @@ 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);
#elif defined(VMW_NOPAGE_2624)
#if defined(VMW_NOPAGE_2624)
static int LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault);
#else
static struct page *LinuxDriverNoPage(struct vm_area_struct *vma,
@@ -883,10 +881,7 @@ LinuxDriverPollTimeout(unsigned long clientData) // IN:
*-----------------------------------------------------------------------------
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
static int
LinuxDriverFault(struct vm_fault *fault) //IN/OUT
#elif defined(VMW_NOPAGE_2624)
#if defined(VMW_NOPAGE_2624)
static int LinuxDriverFault(struct vm_area_struct *vma, //IN
struct vm_fault *fault) //IN/OUT
#else
@@ -895,9 +890,6 @@ static struct page *LinuxDriverNoPage(struct vm_area_struct *vma, //IN
int *type) //OUT: Fault type
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
struct vm_area_struct *vma = fault->vma;
#endif
VMLinux *vmLinux = (VMLinux *) vma->vm_file->private_data;
unsigned long pg;
struct page* page;
@@ -1358,6 +1350,7 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
case IOCTL_VMX86_CREATE_VM:
case IOCTL_VMX86_INIT_CROSSGDT:
case IOCTL_VMX86_SET_UID:
case IOCTL_VMX86_LOOK_UP_MPN:
case IOCTL_VMX86_GET_NUM_VMS:
case IOCTL_VMX86_GET_TOTAL_MEM_USAGE:
case IOCTL_VMX86_SET_HARD_LIMIT:
@@ -1367,6 +1360,8 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
case IOCTL_VMX86_GET_KHZ_ESTIMATE:
case IOCTL_VMX86_GET_ALL_CPUID:
case IOCTL_VMX86_GET_ALL_MSRS:
case IOCTL_VMX86_READ_PAGE:
case IOCTL_VMX86_WRITE_PAGE:
case IOCTL_VMX86_SET_POLL_TIMEOUT_PTR:
case IOCTL_VMX86_GET_KERNEL_CLOCK_RATE:
case IOCTL_VMX86_GET_REFERENCE_CLOCK_HZ:
@@ -1527,7 +1522,7 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
if (retval) {
break;
}
args.ret.status = Vmx86_LookupUserMPN(vm, args.uAddr, &args.ret.mpn);
args.ret.status = HostIF_LookupUserMPN(vm, args.uAddr, &args.ret.mpn);
retval = HostIF_CopyToUser((void *)ioarg, &args, sizeof args);
break;
}
@@ -1846,7 +1841,7 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
if (retval) {
break;
}
retval = HostIF_ReadPage(vm, req.mpn, req.uAddr, FALSE);
retval = HostIF_ReadPage(req.mpn, req.uAddr, FALSE);
break;
}
@@ -1857,7 +1852,7 @@ LinuxDriver_Ioctl(struct file *filp, // IN:
if (retval) {
break;
}
retval = HostIF_WritePage(vm, req.mpn, req.uAddr, FALSE);
retval = HostIF_WritePage(req.mpn, req.uAddr, FALSE);
break;
}
+15 -123
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -73,22 +73,19 @@
#include <linux/capability.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/signal.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include <linux/taskstats_kern.h> // For linux/sched/signal.h without version check
#endif
#include "vmware.h"
#include "x86apic.h"
#include "vm_asm.h"
#include "modulecall.h"
#include "driver.h"
#include "memtrack.h"
#include "phystrack.h"
#include "cpuid.h"
#include "cpuid_info.h"
#include "hostif.h"
#include "hostif_priv.h"
#include "driver.h"
#include "vmhost.h"
#include "x86msr.h"
#include "apic.h"
@@ -1009,7 +1006,7 @@ HostIF_FreeLockedPages(VMDriver *vm, // IN: VM instance pointer
int
HostIF_Init(VMDriver *vm) // IN:
{
vm->memtracker = MemTrack_Init(vm);
vm->memtracker = MemTrack_Init();
if (vm->memtracker == NULL) {
return -1;
}
@@ -2001,15 +1998,15 @@ HostIF_MapCrossPage(VMDriver *vm, // IN
return NULL;
}
vPgAddr = (VA) MapCrossPage(page);
HostIF_VMLock(vm, 27);
HostIF_GlobalLock(16);
if (vm->vmhost->crosspagePagesCount >= MAX_INITBLOCK_CPUS) {
HostIF_VMUnlock(vm, 27);
HostIF_GlobalUnlock(16);
UnmapCrossPage(page, (void*)vPgAddr);
return NULL;
}
vm->vmhost->crosspagePages[vm->vmhost->crosspagePagesCount++] = page;
HostIF_VMUnlock(vm, 27);
HostIF_GlobalUnlock(16);
ret = vPgAddr | (((VA)p) & (PAGE_SIZE - 1));
@@ -2817,75 +2814,13 @@ HostIF_CallOnEachCPU(void (*func)(void*), // IN: function to call
}
/*
*-----------------------------------------------------------------------------
*
* HostIFCheckTrackedMPN --
*
* Check if a given MPN is tracked for the specified VM.
*
* Result:
* TRUE if the MPN is tracked in one of the trackers for the specified VM,
* FALSE otherwise.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
HostIFCheckTrackedMPN(VMDriver *vm, // IN: The VM instance
MPN mpn) // IN: The MPN
{
VMHost * const vmh = vm->vmhost;
if (vmh == NULL) {
return FALSE;
}
HostIF_VMLock(vm, 32); // Debug version of PhysTrack wants VM's lock.
if (vmh->lockedPages) {
if (PhysTrack_Test(vmh->lockedPages, mpn)) {
HostIF_VMUnlock(vm, 32);
return TRUE;
}
}
if (vmh->AWEPages) {
if (PhysTrack_Test(vmh->AWEPages, mpn)) {
HostIF_VMUnlock(vm, 32);
return TRUE;
}
}
if (vm->memtracker) {
if (MemTrack_LookupMPN(vm->memtracker, mpn) != NULL) {
HostIF_VMUnlock(vm, 32);
return TRUE;
}
}
HostIF_VMUnlock(vm, 32);
if (vmx86_debug) {
/*
* The monitor may have old KSeg mappings to pages which it no longer
* owns. Minimize customer noise by only logging this for developers.
*/
Log("%s: MPN %" FMT64 "x not owned by this VM\n", __FUNCTION__, mpn);
}
return FALSE;
}
/*
*----------------------------------------------------------------------
*
* HostIF_ReadPage --
*
* Reads one page of data from a machine page and returns it in the
* specified kernel or user buffer. The machine page must be owned by
* the specified VM.
* puts the content of a machine page into a kernel or user mode
* buffer.
*
* Results:
* 0 on success
@@ -2898,8 +2833,7 @@ HostIFCheckTrackedMPN(VMDriver *vm, // IN: The VM instance
*/
int
HostIF_ReadPage(VMDriver *vm, // IN: The VM instance
MPN mpn, // MPN of the page
HostIF_ReadPage(MPN mpn, // MPN of the page
VA64 addr, // buffer for data
Bool kernelBuffer) // is the buffer in kernel space?
{
@@ -2911,9 +2845,6 @@ HostIF_ReadPage(VMDriver *vm, // IN: The VM instance
if (mpn == INVALID_MPN) {
return -EFAULT;
}
if (HostIFCheckTrackedMPN(vm, mpn) == FALSE) {
return -EFAULT;
}
page = pfn_to_page(mpn);
ptr = kmap(page);
@@ -2937,8 +2868,8 @@ HostIF_ReadPage(VMDriver *vm, // IN: The VM instance
*
* HostIF_WritePage --
*
* Writes one page of data from a kernel or user buffer onto the specified
* machine page. The machine page must be owned by the specified VM.
* Put the content of a kernel or user mode buffer into a machine
* page.
*
* Results:
* 0 on success
@@ -2951,9 +2882,9 @@ HostIF_ReadPage(VMDriver *vm, // IN: The VM instance
*/
int
HostIFWritePageWork(MPN mpn, // MPN of the page
VA64 addr, // data to write to the page
Bool kernelBuffer) // is the buffer in kernel space?
HostIF_WritePage(MPN mpn, // MPN of the page
VA64 addr, // data to write to the page
Bool kernelBuffer) // is the buffer in kernel space?
{
void const *buf = VA64ToPtr(addr);
int ret = 0;
@@ -2980,45 +2911,6 @@ HostIFWritePageWork(MPN mpn, // MPN of the page
return ret;
}
int
HostIF_WritePage(VMDriver *vm, // IN: The VM instance
MPN mpn, // MPN of the page
VA64 addr, // data to write to the page
Bool kernelBuffer) // is the buffer in kernel space?
{
if (HostIFCheckTrackedMPN(vm, mpn) == FALSE) {
return -EFAULT;
}
return HostIFWritePageWork(mpn, addr, kernelBuffer);
}
/*
*-----------------------------------------------------------------------------
*
* HostIF_WriteMachinePage --
*
* Puts the content of a machine page into a kernel or user mode
* buffer. This should only be used for host-global pages, not any
* VM-owned pages.
*
* Results:
* On success: 0
* On failure: a negative error code
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
int
HostIF_WriteMachinePage(MPN mpn, // IN: MPN of the page
VA64 addr) // IN: data to write to the page
{
return HostIFWritePageWork(mpn, addr, TRUE);
}
/*
*----------------------------------------------------------------------
+1 -3
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-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
@@ -205,13 +205,11 @@ skipTaskSwitch:;
uint32 nPages = (uint32)crosspage->args[1];
VA64 uAddr = (VA64)VPN_2_VA(vpn);
ASSERT(nPages <= MODULECALL_NUM_ARGS);
HostIF_VMLock(vm, 38);
for (i = 0; i < nPages; i++) {
MPN mpn;
HostIF_LookupUserMPN(vm, uAddr + i * PAGE_SIZE, &mpn);
crosspage->args[i] = mpn;
}
HostIF_VMUnlock(vm, 38);
break;
}
+5 -10
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998-2013, 2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998-2013 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -1104,7 +1104,7 @@ VNetBridgeNotifyLogBridgeUpError(int errno, // IN: the error number
case -ENODEV:
LOG(0, (KERN_WARNING "bridge-%s: interface %s not found or not "
"up\n", bridgeName, devName));
break;
break;
case -EINVAL:
LOG(0, (KERN_WARNING "bridge-%s: interface %s is not a valid "
"Ethernet interface\n", bridgeName, devName));
@@ -1143,16 +1143,11 @@ VNetBridgeNotifyLogBridgeUpError(int errno, // IN: the error number
static int
VNetBridgeNotify(struct notifier_block *this, // IN: callback data (bridge)
u_long msg, // IN: type of event
void *data) // IN: net_device or notifier info
void *data) // IN: device pertaining to event
{
VNetBridge *bridge = list_entry(this, VNetBridge, notifier);
struct net_device *dev;
struct net_device *dev = (struct net_device *) data;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
dev = netdev_notifier_info_to_dev(data);
#else
dev = (struct net_device *)data;
#endif
switch (msg) {
case NETDEV_UNREGISTER:
LOG(2, (KERN_DEBUG "bridge-%s: interface %s is unregistering\n",
@@ -1184,7 +1179,7 @@ VNetBridgeNotify(struct notifier_block *this, // IN: callback data (bridge)
LOG(1, (KERN_DEBUG "bridge-%s: enabling the bridge on dev up\n",
bridge->name));
errno = VNetBridgeUp(bridge, FALSE);
errno = VNetBridgeUp(bridge, FALSE);
if (errno != 0) {
VNetBridgeNotifyLogBridgeUpError(errno, bridge->name, dev->name);
}
+1 -2
View File
@@ -337,8 +337,7 @@ 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(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE >= 0x0704)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
#define compat_netif_trans_update(d) netif_trans_update(d)
#else
#define compat_netif_trans_update(d) do { (d)->trans_start = jiffies; } while (0)
-3
View File
@@ -36,9 +36,6 @@
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/wait.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include <linux/taskstats_kern.h> // For <linux/sched/signal.h> without version dependency
#endif
#include <net/checksum.h>
#include <net/sock.h>
+9
View File
@@ -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
+2 -2
View File
@@ -1,5 +1,5 @@
/*********************************************************
* Copyright (C) 1998, 2017 VMware, Inc. All rights reserved.
* Copyright (C) 1998 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -77,7 +77,7 @@
extern struct proto vmnet_proto;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) || defined(sk_net_refcnt)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
# define compat_sk_alloc(_bri, _pri) sk_alloc(&init_net, \
PF_NETLINK, _pri, &vmnet_proto, 1)
#elif defined(VMW_NETDEV_HAS_NET)